while 循环中的后递增

发布于 2024-12-02 07:40:36 字数 313 浏览 1 评论 0原文

下面的代码让我有点困惑:

char * strcpy(char * p, const char * q) {
  while (*p++=*q++);
  //return
}

这是 strcpy 函数的精简实现。从这段代码中,我们看到指针 pq 递增然后取消引用,并且 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

猫瑾少女 2024-12-09 07:40:36

由于 ++ 位于变量之后,因此在计算表达式之后之前,它们不会递增。这就是为什么它是后自增运算符;预增量带有前缀 (++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.

短叹 2024-12-09 07:40:36

不,增量发生在分配之后。

如果是*(++p),则指针p将递增,然后赋值。

No, the increment happens after the assignment.

If it were *(++p), the pointer p would be incremented and after that assigned.

唐婉 2024-12-09 07:40:36

p++ 是后递增指针p。因此,在 p 递增之前,p 的当前值由引用运算符 * 进行操作。

如果 while 循环编写如下,那么您的推理是正确的:

while (*++p=*++q);

在这种情况下,增量将在取消引用之前发生。

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.

他夏了夏天 2024-12-09 07:40:36

表达式x++++x 都有结果(值)和副作用

表达式x++结果x的当前值。 副作用x的内容增加1。

表达式++x结果x的当前值加1。副作用与上面相同。

请注意,副作用不必在表达式求值后立即应用;它只需在下一个序列点之前应用。例如,给定代码,

x = 1;
y = 2;
z = ++x + y++;

不能保证在计算表达式 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 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.

错爱 2024-12-09 07:40:36

表达式 (*q++) 的右侧将在 *p++ 之前求值,并且两者仅在赋值后才会递增。

从右向左阅读该语句并记住后递增(q++ 而不是 ++q)发生在该行中的所有其他内容都解决之后。

*q --> dereference q
=  --> assign the value
*p --> to p

两者都增加。

执行此操作,直到 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.

*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.

夏夜暖风 2024-12-09 07:40:36

q++ 的值为 q
++q 的值为 q+1

The value of q++ is q
The value of ++q is q+1

小伙你站住 2024-12-09 07:40:36

这是 strcpy 函数的剥离实现。从这段代码中,我们看到指针 p 和 q 增加,然后取消引用,并且 q 被分配给 p 直到到达 \0 字符。

情况恰恰相反。 *p 处的值设置为 *q,然后两个指针都会递增。

当您有 int foo = bar++ 时,增量会在 foo 设置后发生。要首先发生它,您需要执行 int foo = ++bar

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

格子衫的從容 2024-12-09 07:40:36

while 循环的条件是执行后递增。等效地:

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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文