指针赋值“* foo ++ = * bar ++;”在C中做了什么?

时间:2014-05-09 16:55:38

标签: c pointers

我确定之前已经多次询问过这种情况,但这种情况很难找到。
假设foo和bar都是指向独立数组的指针,这行是做什么的?

*foo++ = *bar++;

每个指针在什么时候递增,是指针或值的分配?
谢谢

5 个答案:

答案 0 :(得分:5)

*foo++ = *bar++;

复制bar分为foo分的所有内容。然后它将两个指针递增到下一个元素。

答案 1 :(得分:2)

postfix ++运算符将递增指针,但表达式foo++的结果是增量之前存储在指针中的地址。取消引用的是foobar在递增之前的值。然后在这些类型上进行分配。它大致相当于

*foo = *bar;
++foo;
++bar;

如果您不熟悉,增加指针会使其指向序列中的下一个元素。以下两个循环完成相同的任务

for (int i = 0; i < 10; ++i) {
    p[i] = 0;
}

for (int i = 0; i <10; ++i, ++p) { // NOTE the extra ++p
    *p = 0;
}

通常只要指向的值不等于某个“end”值,就会递增指针。对于char*,这通常是'\0'字符。您发布的示例通常在使用两种while类型的char*循环中看到。 while(*foo++ = *bar++)。此循环将继续,直到分配给*foo的值为0值,\0字符为。

答案 2 :(得分:2)

由于后递增的优先级高于(比第一个更紧密)一元*运算符,所以:

*foo++ = *bar++;

相当于:

*(foo++) = *(bar++);

表达式foo++产生未修改的foo值;同样,bar++会产生未修改的bar值。 (这不是它所做的全部;我们将在稍后介绍其余部分。)因此,赋值将bar指向的对象的值复制到foo指向的对象中。到目前为止,它相当于:

*foo = *bar;

我认为不需要进一步解释。

表达式foo++的值只是foo的值,但作为副作用,它还会导致foo的值递增。 foo = foo + 1具有相同的副作用(尽管它会产生不同的值)。所以评估

*foo++ = *bar++;

会在某个时刻导致foobar都递增。为此,foobar都需要指向数组的元素,并且每个元素都会被提前指向数组的下一个元素。

未指定出现这些副作用的时间。在foo更新之前或之后,bar*foo的值可以按任意顺序更新。只要foobar是不同的指针,这没关系,因为三个副作用不会相互干扰。

最后,赋值本身就是一个表达式,它产生的值是*foo中存储的值。在这种情况下,该值将被丢弃。

将其分解,并假设foobar的类型为some_type**foo++ = *bar++;可以写成:

some_type *foo_tmp = foo;
some_type *bar_tmp = bar;
*foo_tmp = *bar_tmp;
foo = foo + 1;
bar = bar + 1;

三个任务以某种未指定的顺序执行(允许任何6个可能的命令)。如果订单很重要,则行为未定义。此扩展忽略了赋值所产生的值。

这种表达式可用于实现strcpy()函数:

char *strcpy(char *dest, const char *src) {
    while (*dest++ = *src++)
        ;
}

所有复制都是由用作while循环中的条件的赋值表达式完成的,并且循环完成的测试基于赋值所产生的值,即{{1已复制的值。复制的值为空字符char时,循环终止,该字符被视为错误条件。对于某些人的口味来说,这有点过于简洁,包括我的口味,但这是一个常见的习语。

答案 3 :(得分:1)

举一个简单的例子:

char s1[] = "I am bar";
char s2[10];

char* bar = s1;  // bar points to the first element of s1
char* foo = s2;  // foo points to the first element of s2

*foo++ = *bar++; // Copies 'I' to s2[0]
                 // Now bar points to the second element of s1
                 // foo points to the second element of s2

*foo++ = *bar++; // Copies ' ' to s2[1]
                 // Now bar points to the third element of s1
                 // foo points to the third element of s2

答案 4 :(得分:0)

增量后运算符++的优先级高于间接运算符*。因此,以下陈述是等效的

*foo++ = *bar++;
// equivalent to
*(foo++) = *(bar++);
  

每个指针在什么时候递增,并且它是一个   指针或值的分配?

foo++评估为foo。它的副作用是增加指针foo以使其指向下一个元素。

同样bar++评估为bar,其副作用是使bar指向下一个元素。 因此,此语句将bar指向的对象分配给foo 指向的对象。 副作用发生在下一个序列点之前。在这种情况下,它是以分号标记的语句的结尾。因此,在执行赋值语句后,指针foobar会递增。