我确定之前已经多次询问过这种情况,但这种情况很难找到。
假设foo和bar都是指向独立数组的指针,这行是做什么的?
*foo++ = *bar++;
每个指针在什么时候递增,是指针或值的分配?
谢谢
答案 0 :(得分:5)
*foo++ = *bar++;
复制bar
分为foo
分的所有内容。然后它将两个指针递增到下一个元素。
答案 1 :(得分:2)
postfix ++运算符将递增指针,但表达式foo++
的结果是增量之前存储在指针中的地址。取消引用的是foo
和bar
在递增之前的值。然后在这些类型上进行分配。它大致相当于
*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++;
会在某个时刻导致foo
和bar
都递增。为此,foo
和bar
都需要指向数组的元素,并且每个元素都会被提前指向数组的下一个元素。
未指定出现这些副作用的时间。在foo
更新之前或之后,bar
和*foo
的值可以按任意顺序更新。只要foo
和bar
是不同的指针,这没关系,因为三个副作用不会相互干扰。
最后,赋值本身就是一个表达式,它产生的值是*foo
中存储的值。在这种情况下,该值将被丢弃。
将其分解,并假设foo
和bar
的类型为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
指向的对象。 副作用发生在下一个序列点之前。在这种情况下,它是以分号标记的语句的结尾。因此,在执行赋值语句后,指针foo
和bar
会递增。