C Pointer Arithmetic on Characters
I have the following code that crashes at the line where I am initializing ch
:
char * p = "Test";
char ch = *p++;
printf("Here : %s\n%c", p, ch);
However the following code has no problem:
char * p = "Test";
char 开发者_开发知识库ch = *p++;
ch++;
printf("Here : %s\n%c", p, ch);
In the first situation, you're trying to change the T
in the "Test" string compiled into the program, which is held in a part of memory that your code isn't meant to change (usually; there are some environments where it's allowed, but usually it isn't). That's because (*p)++
means (loosely speaking) *p = *p + 1
(e.g., get the character pointed to by p
, increment it, and write it back), and of course, *p
is pointing to the compiled-in "Test".
Your second version doesn't have that problem, because you're incrementing ch
, which you are allowed to change. Your second version actually increments two different things, in fact; first it does char ch = *p++;
which retrieves the character at *p
and then increments p
(now it points to the "e" in "Test"), and then you do ch = ch++
. (You probably meant just ch++;
there, since ++
operates directly on its operand.)
The problem comes down to operator precedence and use of parentheses ()
.
char ch = (*p)++;
This line will (attempt to) increment the character at the address stored in p
char ch = *p++;
This one sets ch
equal to the character at the address stored in p
, then increments the address stored in p
. The ++
operator takes precedence over the pointer dereference operator, so it will be executed first. To be clear, the second line is equivalent to:
char ch = *(p++);
Your first example increments the value at *p
. Since p points to a string constant, this is not allowed with many compilers.
Your second example increments the pointer, not the value it points to.
This code:
(*p)++
is trying to increment the value that p points to. p is pointing to the const char string "Test", which cannot be modified.
The first version is doing this:
char * p = "Test"; //this should really be const char *
*p = *p + 1; //CRASH! attempthing to modifiy the contents of a string literal
char ch = *p;
ch = ch++; //This is excessive, ch++ on it's own would do the same
printf("Here : %s\n%c", p, ch);
While the second version is doing this:
char * p = "Test"; //still should be const char *
char ch = *p;
p++; //p now points to "est"
ch = ch++;
printf("Here : %s\n%c", p, ch); //prints est\nU
精彩评论