“How can a pointer to a character data type can hold a string data type?” Well, it’s partly true that in C, type ‘pointer to char’ is the string type. Any function that operates on strings (including printf
) will be found to accept these strings via parameters of type char *
.
“How can printf()
print a string when no apparent quotation marks are used?” There’s no rule that says you need quotation marks to have a string! That thing with quotation marks is a string constant or string literal, and it’s one way to get a string into your program, but it’s not at all the only way. There are lots of ways to construct (and manipulate, and modify) strings that don’t involve any quotation marks at all.
Let’s draw some pictures representing your code:
char *p;
p
is a pointer to char
, but as you correctly note, it doesn’t point anywhere yet. We can represent it graphically like this:
+-----------+
p: | ??? |
+-----------+
Next you set p
to point somewhere:
p = "%d";
This allocates the string "%d"
somewhere (it doesn’t matter where), and sets p
to point to it:
+---+---+---+
| % | d |\0 |
+---+---+---+
^
|
\
\
\
|
+-----|-----+
p: | * |
+-----------+
Next, you start incrementing p
:
p++;
As you said, this makes p
point one past where it used to, to the second character of the string:
+---+---+---+
| % | d |\0 |
+---+---+---+
^
|
|
|
|
|
+-----|-----+
p: | * |
+-----------+
Next,
p++;
Now we have:
+---+---+---+
| % | d |\0 |
+---+---+---+
^
|
/
/
/
|
+-----|-----+
p: | * |
+-----------+
Next you called printf
, but somewhat strangely:
printf(p-2,23);
The key to that is the expression p-2
. If p
points to the third character in the string, then p-2
points to the first character in the string:
+---+---+---+
| % | d |\0 |
+---+---+---+
^ ^
+----|----+ |
p-2: | * | /
+---------+/
/
|
+-----|-----+
p: | * |
+-----------+
And that pointer, p-2
, is more or less the same pointer that printf
would have received if you’re more conventionally called printf("%d", 23)
.
Now, if you thought printf
received a string, it may surprise you to hear that printf
is happy to receive a char *
instead — and that in fact it always receives a char *
. If this is surprising, ask yourself, what did you thing printf
did receive, if not a pointer to char
?
Strictly speaking, a string in C is an array of characters (terminated with the '\0'
character). But there’s this super-important secret fact about C, which if you haven’t encountered yet you will real soon (because it’s really not a secret at all):
You can’t do much with arrays in C. Whenever you mention an array in an expression in C, whenever it looks like you’re trying to do something with the value of the array, what you get is a pointer to the array’s first element.
That pointer is pretty much the “value” of the array. Due to the way pointer arithmetic works, you can use pointers to access arrays pretty much transparently (almost as if the pointer was the array, but of course it’s not). And this all applies perfectly well to arrays of (and pointers to) characters, as well.
So since a string in C is an array of characters, when you write
"%d"
that’s an array of three characters. But when you use it in an expression, what you get is a pointer to the array’s first element. For example, if you write
printf("%d", 23);
you’ve got an array of characters, and you’re mentioning it in an expression, so what you get is a pointer to the array’s first element, and that’s what gets passed to printf
.
If we said
char *p = "%d";
printf(p, 23);
we’ve done the same thing, just a bit more explicitly: again, we’ve mentioned the array "%d"
in an expression, so what we get as its value is a pointer to its first element, so that’s the pointer that’s used to initialize the pointer variable p
, and that’s the pointer that gets passed as the first argument to printf
, so printf
is happy.
Up above, I said “it’s partly true that in C, type ‘pointer to char’ is the string type”. Later I said that “a string in C is an array of characters”. So which is it? An array or a pointer? Strictly speaking, a string is an array of characters. But like all arrays, we can’t do much with an array of characters, and when we try, what we get is a pointer to the first element. So most of the time, strings in C are accessed and manipulated and modified via pointers to characters. All functions that operate on strings (including printf
) actually receive pointers to char, pointing at the strings they’ll manipulate.
1
solved What is the output of the following code in C? [closed]