Let's say s is the string "PaxDiablo", stored in memory at location 1 thus:
s
|
V
+---+---+---+---+---+---+---+---+---+----+
| P | a | x | D | i | a | b | l | o | \0 |
+---+---+---+---+---+---+---+---+---+----+
Address: 1 2 3 4 5 6 7 8 9 10
The expression t = s + len - 1 (where len is 9 in this case) sets t to eight characters past s.
s t
| |
V V
+---+---+---+---+---+---+---+---+---+----+
| P | a | x | D | i | a | b | l | o | \0 |
+---+---+---+---+---+---+---+---+---+----+
Address: 1 2 3 4 5 6 7 8 9 10
In other words, it gives you the address of the last character in the string.
The rest of the code then iterates over the string in a backwards direction, by decrementing t until it passes s.
Technically, this is undefined behaviour since you're only every supposed to compare pointers where they point to the same array on one character beyond (here we are comparing t where it's one character before the array), but you'd struggle to find a system on which this didn't work.
As Potatoswatter (I absolutely love some of the names people choose here on SO) points out in a comment, you can avoid that comparison by using the do {} while construct rather than while {}:
#include <stdio.h>
#include <string.h>
void printReverse (char *str) {
size_t len = strlen (str);
if (len != 0) {
char *pStr = str + len;
do {
putchar (*(--pStr));
} while (pStr > str);
}
putchar ('\n');
}