The variable s
is a pointer to the first out of a series of characters which are consecutive in memory (colloquially referred to as a "string", though it's not quite the same). It's a pointer to a character, thus char *
.
Dereferencing s
(by doing *s
) gives you the first of those characters, h
, whose type is now just char
. One layer of indirection was stripped away.
Thus, the issue is that you're trying to pass a character (char
), where a string (char *
) was expected. char *
was expected because you used the %s
type character in your format string to printf
. Instead, you should use %c
, which expects single, simple char
.
The mistake here is actually quite grave. If you were allowed to pass this 'h'
where a char *
was expected, you would end up with the ASCII code of 'h'
(0x68
) being passed where a pointer was expected. printf
would be none-the-wiser, and would try to dereference that value, treating 0x68
like a pointer to the beginning of a string. Of course, that's probably not a valid memory location in your program, so that should seg-fault pretty reliability, if it were allowed to happen.