在C中复制字符串

时间:2010-02-09 04:03:15

标签: c pointers string pointer-arithmetic

我对此代码感到困惑:(http://www.joelonsoftware.com/articles/CollegeAdvice.html

while (*s++ = *t++);

执行的顺序是什么?是* s = * t首先完成,然后它们各自递增?或者其他方式?

感谢。

编辑:如果它是:

while(*(s++) = *(t++));

while(++*s = ++*t);

7 个答案:

答案 0 :(得分:14)

while (*s++ = *t++);

precedence table,您可以清楚地看到++的优先级高于*。但是++在这里用作后增量运算符,因此增量发生在赋值表达式之后。所以*s = *t首先发生,然后s和t递增。

修改

while(*(s++) = *(t++));

与上述相同。通过使用括号,您可以更明确地使用它。但请记住++仍然是一个后期增量。

while(++*s = ++*t);

s旁边只有一个操作员。因此,首先应用*,然后应用++结果导致lvalue required错误。

while(*++s = *++t);

再次只是s,t旁边的运算符。因此,首先进行增量,然后进行复制。所以我们有效地将第一个字符的副本从t跳到s。

答案 1 :(得分:4)

你是对的。 * s = * t先完成,然后递增。

答案 2 :(得分:2)

增量是后增量。发布不仅仅是因为它是在变量递增之后,而且因为它是在表达式被评估之后出现的。所以执行顺序是

*s = *t

然后是s ++和t ++

答案 3 :(得分:1)

EDIT ::

@chrisgoyal

执行顺序是一个含糊不清的术语。这里有两件不同的事情。语法顺序和表达式的语义。

从语法上讲,首先应用operator ++。如果首先应用* s,那么以下内容相当于@Hogan所说的:

(*s)++ = (*t)++

非常与Joel的样本不同。

operator ++的语义是它在表达式之后执行。

希望澄清我的肉。


实际上,首先应用s++t++。不要忘记在表达式完成后执行后修复操作符。基本上,运算符++适用于两者,然后执行 *s = *t

答案 4 :(得分:0)

在Post增量操作中,首先使用变量,然后再使用变量。

答案 5 :(得分:0)

所以有两种增量形式

++s // increment before using value
s++ // increment after using value

可以取消引用这些结果:

*++s // or...
*s++

这在第一台运行C的机器之一上运行得非常好,PDP-11有一个寄存器间接寻址模式,可以在之后递增寄存器。以下操作在硬件中可用:

*--s // or
*s++

你可以做任何一件事

*x++ = *y++; // or
*--x = *--y; // or some combination

如果你这样做,整条线都发生在一条指令中。因为//评论是由C99引入的,所以你实际上无法逃脱我的评论语法。

答案 6 :(得分:0)

代码:(while *s++ = *t++);大致相当于:

while (*s = *t) {
    ++s;
    ++t;
}

第二个完全相同 - 额外的parens不会改变任何东西(在这种情况下)。为了让parens做任何事情,他们必须像:while ((*s)++ = (*t)++);。这与第三个例子大致相同(见下段所述)。

最后一个例子:while(++*s = ++*t);完全不同。由于取消引用(*)更靠近操作数,因此取消引用操作数,并递增取消引用的结果,这意味着它递增指针指向AT的内容,而不是递增指针本身。结果,这将复制第一个字符,然后递增该字符,然后检查该字符是否为非零并继续相同直到它为零。结果是源和目标都变成空字符串(因为两者的第一个字符现在都是零,用于终止字符串)。