Think of memory laid out like this:
| [0] | [1] | [2] | [3] | [4] | [5] | <- indexes
+-----+-----+-----+-----+-----+-----+
s: | A | b | h | a | s | nul | <- characters
| 65 | 98 | 104 | 97 | 115 | 0 | <- integral values (if ASCII)
+-----+-----+-----+-----+-----+-----+
The following expression-address map shows what is happening:
s -> s -> &(s[0])
s + s[1] -> s + 98 -> &(s[98])
s + s[1] - s[3] -> s + 98 - 97 -> s + 1 -> &(s[1])
Of these, only the first and third are legal as they end up within the bounds of the string. The second is undefined.
The first gives you the address of the string itself, so you see Abhas
.
The third gives you the address of the second character of the string, so you see bhas
.
The second gives you something well outside the string and will therefore give you whatever it wants. In fact, as undefined behaviour, it can give you anything, nothing, crash, format your disks, laugh maniacally through your sound card, or even collapse to a naked singularity, taking a large chunk of our planet with it.
I should mention of course that, outside of educating you as to how pointers may work, that code should never be used or seen in the wild. It is a classic example of how not to code.