To answer your question, we need to get rid of some syntactic sugar first and know exactly what b
is:
char *b;
b = "Computer";
is (almost) equivalent to
const char *b;
const char str[] = {'C', 'o', 'm', 'p', 'u', 't', 'e', 'r', '\0'};
b = &str[0];
Meaning b
is a pointer to the first element in an array of char
elements. Or simpler, b
just points to a char
printf("%c", *b)
expects a char
(%c
), and by using *b
we are giving printf
the first char
from the string (or char
array) "Computer"
printf("%s", b)
expects a pointer (%s
). We are thus providing b
which points to "Computer"
. Why? Because under the hood, printf
starts at a location, reads a character and goes to the next location (which is b + 1
). It does that until printf
reads the value 0
somewhere along its path.
So the core idea is that you're indeed dealing with a pointer, but printf
needs itself a pointer to go through an array of char
Note that the charatcer '0'
is not the number 0
, but the number 0
is equal to the character '\0'
which is what you sometimes see in char
arrays like in my example.
As an extra on why the above snippets are not exactly the same: A string in code is stored in a read-only location, whereas the assignment as an array of characters is stored in modifiable memory. The const
keyword ensures immutability, but both of these strings are still stored in entirely different locations and thus behaviour might not be the same.