Post-increment in a while loop
The following code confused me a bit:
char * strcpy(char * p, const char * q) {
while (*p++=*q++);
//return
}
This is a stripped down implementation of strcpy
function. From this code, we see that pointer p
and q
are incremented then dereferenced and q
is assigned to p
until the \0
char has been reached.
I开发者_运维技巧 would like someone to explain the first iteration of the while loop.
Because the ++
is after the variables, they aren't incremented until after the expression is evaluated. That's why it's the post-increment operator; the pre-increment is prefixed (++p
). *++p
would write to the second spot, *p++
writes to the first.
No, the increment happens after the assignment.
If it were *(++p)
, the pointer p
would be incremented and after that assigned.
p++
is post-incrementing the pointer p
. So the current value of p
is operated upon by the deference operator *
before p
is incremented.
Your reasoning would've been correct if the while
loop was written as follows:
while (*++p=*++q);
In this case the increment would happen before dereferencing.
The expressions x++
and ++x
have both a result (value) and a side effect.
The result of the expression x++
is the current value of x
. The side effect is that the contents of x
are incremented by 1.
The result of the expression ++x
is the current value of x
plus 1. The side effect is the same as above.
Note that the side effect doesn't have to be applied immediately after the expression is evaluated; it only has to be applied before the next sequence point. For example, given the code
x = 1;
y = 2;
z = ++x + y++;
there's no guarantee that the contents of x
will be modified before the expression y++
is evaluated, or even before the result of ++x + y++
is assigned to z
(neither the =
nor +
operators introduce a sequence point). The expression ++x
evaluates to 2, but it's possible that the variable x
may not contain the value 2 until after z
has been assigned.
It's important to remember that the behavior of expressions like x++ + x++
is explicitly undefined by the language standard; there's no (good) way to predict what the result of the expression will be, or what value x
will contain after it's been evaluated.
Postfix operators have a higher precedence than unary operators, so expressions like *p++
are parsed as *(p++)
(i.e., you're applying the *
operator to the result of the expression p++
). Again, the result of the expression p++
is the current value of p
, so while (*p++=*q++);
doesn't skip the first element.
Note that the operand to the autoincrement/decrement operators must be an lvalue (essentially, an expression that refers to a memory location such that the memory can be read or modified). The result of the expression x++
or ++x
is not an lvalue, so you can't write things like ++x++
or (x++)++
or ++(++x)
. You could write something like ++(*p++)
(p++
is not an lvalue, but *p++
is), although that would probably get you slapped by anyone reading your code.
The right hand side of the expression (*q++) will be evaluated prior to *p++, and both will only be incremented after the assignment takes place.
Read the statement right to left and remember post-increment (q++ instead of ++q) happens after everything else in the line is resolved.
*q --> dereference q
= --> assign the value
*p --> to p
increment both.
Do this until q p taking q's element = 0 which is when it reaches the null terminator.
The value of q++
is q
The value of ++q
is q+1
This is a stripped implementation of strcpy function. From this code, we see that pointer p and q are increamented, than dereferenced and q is assigned to p until \0 char has been reached.
It happens the other way around. The value at *p
is set to *q
, then both pointers are incremented.
When you have int foo = bar++
the increment happens after foo has been set. To have it happen first you would do int foo = ++bar
The while
loop's condition is performing post-increment. Equivalently:
while (true) {
char* old_p = p;
const char* old_q = q;
++p; // or p++;
++q; // or q++;
*old_p = *old_q;
if (*old_p == '\0')
break;
}
精彩评论