在C中复制字符串
我对此代码感到困惑:(http://www.joelonsoftware.com/articles/CollegeAdvice。 html)
while (*s++ = *t++);
执行顺序是什么? *s = *t 是先完成,然后它们各自递增吗?或者其他方式?
谢谢。
编辑:如果是的话怎么办:
while(*(s++) = *(t++));
并且
while(++*s = ++*t);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
从优先级表中你可以清楚地看到
++< /code> 的优先级高于
*
。但这里使用++
作为后增量运算符,因此增量发生在赋值表达式之后。所以*s = *t
首先发生,然后 s 和 t 递增。编辑:
与上面相同。您可以通过使用括号使其更加明确。但请记住
++
仍然是后期增量。s 旁边只有一个运算符。因此,首先应用
*
,然后应用++
,这会导致lvalue required
错误。再次只是 s,t 旁边的运算符。所以首先发生增量,然后发生复制。因此,我们实际上跳过了从 t 到 s 的第一个字符的副本。
From the precedence table you can clearly see
++
is having higher precedence than*
. But++
is used here as post increment operator, so the incrementation happens after the assignment expression. So*s = *t
happens first, then s and t are incremented.EDIT:
Is same as above. You are making it more explicit with the use of parenthesis. But remember
++
is still a post increment.There is just one operator next to s. So
*
is applied first and on that result++
is applied which results in thelvalue required
error.Again just operator next to s,t. So the incrementation happens first followed by copy. So we are effectively skipping the copy of the first char from t to s.
你是对的。首先执行*s = *t,然后递增。
You are right. *s = *t is done first, and then they are incremented.
该增量是后增量。发布不仅因为它发生在变量递增之后,还因为它发生在表达式求值之后。所以执行顺序就是
s++和t++
The increment is a post-increment. Post not just because it comes after the variable being incremented, but also because it comes after the expression is evaluated. So the order of execution is
then s++ and t++
编辑::
@chrisgoyal
执行顺序是一个不明确的术语。这里有两件事不同。语法顺序和表达式的语义。
从语法上讲,首先应用运算符 ++。如果首先应用 *s,则以下内容相当于 @Hogan 所说的:
这与 Joel 的示例非常不同。
运算符++的语义是它在表达式之后执行。
希望这能澄清我吃的是什么。
实际上,首先应用的是
s++
和t++
。不要忘记后修复运算符是在表达式完成后执行的。基本上,运算符++
应用于两者,然后*s = *t
被执行。EDIT::
@chrisgoyal
Order of execution is an ambiguous term. There are two different things here. The syntactical order, and the semantics of the expression.
Syntactically, the operator ++ is applied first. If the *s is applied first, then the following is equivalent to what @Hogan said:
Which is very different from Joel's sample.
The semantics of the operator ++ is that it is executed after the expression.
Hope that clarifies what I meat.
Actually,
s++
andt++
are applied first. Don't forget that the post-fix operator is executed after the expression is done. Basically the operator++
is applied for both, then*s = *t
is executed.在后增量操作中,首先使用变量,然后在修改变量后使用变量。
In Post increment operation variable is used first and then after its gets modified.
因此,有两种形式的增量,
并且这些结果可以取消引用:
这在最早运行 C 的机器之一 PDP-11 上效果非常好,它具有寄存器间接寻址模式,可以增量之后注册。以下操作可在硬件中使用:
您可以执行任一操作
,如果执行了,则整行操作都发生在一条指令中。然而,由于 // 注释是由 C99 引入的,因此您实际上无法摆脱我的注释语法。
So there are two forms of increment
And the result of these can be dereferenced:
This worked out really well on one of the very first machines for C to run on, the PDP-11, which had a register-indirect addressing mode that increment the register after. The following ops were available in hardware:
You could do either
And if you did, the whole line happened in a single instruction. Since // comments were introduced by C99, however, you couldn't actually get away with my comment syntax.
代码:
(while *s++ = *t++);
大致相当于:第二个完全相同 - 额外的括号不会改变任何内容(在本例中)。对于要执行任何操作的括号,它们必须类似于:
while ((*s)++ = (*t)++);
。这与您的第三个示例大致相同(在下面的段落中介绍)。最后一个示例:
while(++*s = ++*t);
完全不同。由于解引用 (*
) 更接近操作数,因此会解引用操作数,并递增解引用的结果,这意味着它会递增指针指向 AT 的内容,而不是递增指针本身。结果,这将复制第一个字符,然后递增该字符,然后检查该字符是否非零并继续相同的操作直到它为零。结果将是源和目标都变成空字符串(因为两者的第一个字符现在都是零,用于终止字符串)。The code:
(while *s++ = *t++);
is roughly equivalent to:The second is exactly the same -- the extra parens don't change anything (in this case). For the parens to do anything, they'd have to be like:
while ((*s)++ = (*t)++);
. This would do roughly the same as your third example (covered in the paragraph below).The last example:
while(++*s = ++*t);
is completely different. Since the dereference (*
) is closer to the operand, this dereferences the operand, and increments the result of the dereference, which means it increments what the pointer points AT, instead of incrementing the pointer itself. As a result, this would copy the first character, then increment that character, then check whether that character was non-zero and continue the same until it was zero. The result would be both the source and the destination becoming empty strings (since the first character of both would now be a zero, which is used to terminate strings).