while 循环中的后递增
下面的代码让我有点困惑:
char * strcpy(char * p, const char * q) {
while (*p++=*q++);
//return
}
这是 strcpy
函数的精简实现。从这段代码中,我们看到指针 p
和 q
递增然后取消引用,并且 q
被分配给 p
直到已达到 \0
字符。
我希望有人解释一下 while 循环的第一次迭代。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
由于
++
位于变量之后,因此在计算表达式之后之前,它们不会递增。这就是为什么它是后自增运算符;预增量带有前缀 (++p
)。*++p
将写入第二个位置,*p++
将写入第一个位置。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.不,增量发生在分配之后。
如果是
*(++p)
,则指针p
将递增,然后赋值。No, the increment happens after the assignment.
If it were
*(++p)
, the pointerp
would be incremented and after that assigned.p++
是后递增指针p
。因此,在p
递增之前,p
的当前值由引用运算符*
进行操作。如果
while
循环编写如下,那么您的推理是正确的:在这种情况下,增量将在取消引用之前发生。
p++
is post-incrementing the pointerp
. So the current value ofp
is operated upon by the deference operator*
beforep
is incremented.Your reasoning would've been correct if the
while
loop was written as follows:In this case the increment would happen before dereferencing.
表达式
x++
和++x
都有结果(值)和副作用。表达式
x++
的结果是x
的当前值。 副作用是x
的内容增加1。表达式
++x
的结果是x
的当前值加1。副作用与上面相同。请注意,副作用不必在表达式求值后立即应用;它只需在下一个序列点之前应用。例如,给定代码,
不能保证在计算表达式
y++
之前,甚至在++x 结果之前修改
被分配给x
的内容+ y++z
(=
和+
运算符都不会引入序列点)。 表达式++x
的计算结果为 2,但变量x
可能直到z< 之后才包含值 2 /code> 已被分配。
重要的是要记住,像
x++ + x++
这样的表达式的行为是语言标准明确未定义的;没有(好的)方法来预测表达式的结果是什么,或者 x 被求值后将包含什么值。后缀运算符比一元运算符具有更高的优先级,因此像
*p++
这样的表达式会被解析为*(p++)
(即,您正在应用*
code> 运算符到表达式p++
的结果)。同样,表达式p++
的结果是p
的当前值,因此while (*p++=*q++);
不会跳过第一个元素。请注意,自动递增/递减运算符的操作数必须是左值(本质上是引用内存位置的表达式,以便可以读取或修改内存)。表达式
x++
或++x
的结果不是左值,因此您不能编写类似++x++ 的内容
或(x++)++
或++(++x)
。您可以编写类似++(*p++)
的内容(p++
不是左值,但*p++
是),尽管这可能会让任何阅读你的代码的人打你一巴掌。The expressions
x++
and++x
have both a result (value) and a side effect.The result of the expression
x++
is the current value ofx
. The side effect is that the contents ofx
are incremented by 1.The result of the expression
++x
is the current value ofx
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
there's no guarantee that the contents of
x
will be modified before the expressiony++
is evaluated, or even before the result of++x + y++
is assigned toz
(neither the=
nor+
operators introduce a sequence point). The expression++x
evaluates to 2, but it's possible that the variablex
may not contain the value 2 until afterz
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 valuex
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 expressionp++
). Again, the result of the expressionp++
is the current value ofp
, sowhile (*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.表达式 (*q++) 的右侧将在 *p++ 之前求值,并且两者仅在赋值后才会递增。
从右向左阅读该语句并记住后递增(q++ 而不是 ++q)发生在该行中的所有其他内容都解决之后。
两者都增加。
执行此操作,直到 qp 取 q 的元素 = 0,即到达 null 终止符。
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.
increment both.
Do this until q p taking q's element = 0 which is when it reaches the null terminator.
q++
的值为 q++q
的值为q+1
The value of
q++
is qThe value of
++q
isq+1
情况恰恰相反。
*p
处的值设置为*q
,然后两个指针都会递增。当您有
int foo = bar++
时,增量会在 foo 设置后发生。要首先发生它,您需要执行int foo = ++bar
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 doint foo = ++bar
while
循环的条件是执行后递增。等效地:The
while
loop's condition is performing post-increment. Equivalently: