I am really confused about the use of pointers on strings. It feels like they obey different rules. Consider the following code
char *ptr = "apple";// perfectly valid here not when declaring afterwards like next
ptr = "apple"; // shouldn't it be *ptr = "apple"
Also printf()
behaves differently -
printf("%s", ptr) // Why should I send the address instead of the value
Also I came across the following code in a book
char str[]="Quest";
char *p="Quest";
str++; // error, constant pointer can't change
*str='Z'; // works, because pointer is not constant
p++; // works, because pointer is not constant
*p = 'M'; // error, because string is constant
I can't understand what is supposed to imply
Please help, I can't find any info anywhere else
char *ptr;
ptr = "apple"; // shouldn't it be *ptr = "apple"
No, because *ptr
would be a char
. So, you may write *ptr = 'a'
but you can't write as you suggest.
printf("%s", ptr) // Why should I send the address instead of the value
Because a string in C, is the address of a sequence of characters (char
) terminated by zero (the null character aka \x0
).
char str[] = "Quest";
char *p = "Quest";
str++; // error, constant pointer can't change
No, a pointer can perfectly change, but here, str
is an array (which is slightly different from being a pointer). But, thus, it cannot deal with pointer arithmetic.
*str='Z'; // works, because pointer is not constant
No, it works because *str
should be a char
.
p++; // works, because pointer is not constant
No, it works because, this time, this is a pointer (not an array).
*p = 'M'; // error, because string is constant
Same as above, this is a char
again, so it works because it is the right type and not because the string is 'constant'. And, as stated by Michael Walz in the comments, even though it might compile, it will produce an undefined behavior at runtime (most likely a crash with segfault
) because the specification do not tell if the string pointed by *p
is read-only or not (yet, it seems that most of the modern compilers implementation decide to make it in read-only). Which might produce a segfault
.
For more information, refer to this SO question.
1- I think you are making some confusion with variable declaration and definition. This line:
char *ptr = "apple";
declares a pointer to char and assigns the address of the first character "a" to the variable ptr. This line is equivalent to the following 2:
char* ptr;
ptr = "apple";
Now, string literals in C are read only. They are implicitly constant, it's the same as doing
const char* ptr;
So in fact, you can not change the contents of the location this pointer points to. Now, even if you could, the way you did it is wrong. Because ptr points to the location of the first character of the string, when you do *ptr you are accessing the contents of the first char of that string. So it expects a char, not a string. So it would be something like: *ptr = 'a'
;
2- Well, that's the way printf works. If you want to print a string with the %s specifier, it expects a pointer to that string, the address of the string's first character, not the string's value itself.
3- Now I'm going to comment your code.
str++; // error, constant pointer can't change
You are correct. Other people keep saying that arrays and pointers are slightly different, but they are not. Arrays are just an abstraction for the programmer to say that you're storing a sequence of values. At the assembly level, there is no difference at all. You could say that arrays are immutable pointers with mutable contents. An array stores the address of the first element of the sequence of values. You can change the contents of the array, but you can't change the address(the first element it points to).
*str='Z'; // works, because pointer is not constant
Now you're making some confusion. The pointer is actually constant, that is, you can not change the address it stores. But you can change the content the address points to, which is what the line above is doing. It's changing the first value of the sequence of values from the array.
p++; // works, because pointer is not constant
Correct. The pointer is not constant, although the content it points to is. You can change the address the pointer stores, but not the value it points at. String literals are mutable pointers to immutable strings.
*p = 'M'; // error, because string is constant
Correct, the string is immutable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With