So my code snippet is this
char* ptr = "Hello";
Here ptr
points to what? I think it points to "H".
Why doesn't this pointer ptr
behave like a normal pointer?
Because when I wrote printf("%s" ,*ptr)
, it didn't give me the value but instead raised an error. Yet when I wrote printf("%s" , ptr)
it gave me "Hello" as output.
Why does this behavior happen?
What is actually stored in pointer ptr
?
CodePudding user response:
Your core misunderstanding here may be that you think that a "string" is a thing that you can pass around and do things with in your program, just like you can with an int or a float or a structure. When you tried to write
printf("%s", *ptr);
perhaps you thought that ptr
was a pointer, but you didn't want to print the pointer, you wanted to print the whole string pointed to by the pointer, so you put that *
in there to "take the contents of the pointer".
The flaw in your reasoning is that there is no such thing, in C, as a string that you might be able to, say, pass as a whole to printf
for it to print.
C does have strings, of course, but they're implemented as arrays. And arrays are second-class citizens in C: you can most definitely not pass them around and do things with them the way you can with ints, floats, and structs.
Whenever you try to do something with an array, what you get (whether you wanted it or not, whether you realized it or not) is a pointer to the array's first element.
So even though we say that the %s
format in printf
is for printing "a string", what printf
does not expect is that you will pass the entire string to it — because printf knows you will have no way of doing that. So, instead, the %s
format in printf
expects to receive a pointer to the first character in the string.
CodePudding user response:
So my code snippet is this
char* ptr = "Hello";
Here
ptr
points to what? I think it points to "H".
ptr
points to the first character of a six-element array of char
containing the characters 'H', 'e', 'l', 'l', 'o', '\0'. The specific char
stored in the location to which ptr
points is 'H'. Note well that that is different from the string "H"
.
Why doesn't this pointer
ptr
behave like a normal pointer?
It behaves exactly like any other char
pointer, with one caveat (which you have not exercised): because it points to a character inside a string literal, you must not attempt to use it to modify that character or others in the literal.
Because when I wrote
printf("%s" ,*ptr)
, it didn't gave me the value but instead instead raised an error.
Well yes, that's reasonable, although you cannot rely on an error here. When you write bogus code like that, you may just get weird behavior. Or even normal-seeming behavior.
If you want to print the one char
to which ptr
directly points, then the correct formatting directive is %c
:
printf("%c" ,*ptr); /* *ptr is a char, not a pointer to one */
Yet when I wrote
printf("%s" , ptr)
it gave me "Hello" as output.
The %s
directive, on the other hand, expects its argument to be a pointer to the first character of a string (as ptr
indeed is), and the whole pointed-to string is printed.
Why does this behavior happen?
Because that's what's supposed to happen. It's unclear why you expected something else.
What is actually stored in pointer ptr ?
The address of the first character of the string literal "Hello"
.
CodePudding user response:
char *ptr = "Hello";
ptr
points to H
H
is a char.
So you need to have - printf("%c", *ptr);
to print just the char.
This is the same as printf("%c", ptr[0]);
Obviously %s
is an array of chars, so %s
will print the entire string.
CodePudding user response:
It has nothing to do with what the char*
points at. The %s
specifier of printf
family of functions is simply defined to expect a nul-terminated character array as parameter.
printf("%s" ,*ptr)
is an undefined behavior and anything can happen.
What is actually stored in pointer ptr ?
The address of the string literal/character array "Hello"
, located in read-only memory. Or the first item of that array if you will, same address.