基本上这是一个将值写入int数组的简单函数 我想为当前元素分配一个值,打印它并将索引输出,并将索引自我增加到下一个元素 但是,自增量顺序的变化会使结果不同。
#include <stdio.h>
int buff[5];
int id;
void write ( )
{
int i;
i = id = 0;
printf("Iter 1\n");
while (i++ < 5) {
buff[id] = id;
printf("writes %d in buff[%d]\n", buff[id], id++);
}
i = id = 0;
printf("Iter 2\n");
while (i++ < 5) {
buff[id] = id;
printf("writes %d in buff[%d]\n", buff[id++], id);
}
}
int main ( )
{
write();
}
-------------
Output:
Iter 1
writes 0 in buff[0]
writes 0 in buff[1] // which should not be 0
writes 0 in buff[2] // which should not be 0
writes 0 in buff[3] // which should not be 0
writes 5 in buff[4] // which should not be 5
Iter 2
writes 0 in buff[0]
writes 1 in buff[1]
writes 2 in buff[2]
writes 3 in buff[3]
writes 4 in buff[4]
我知道在表达式中对同一个变量进行多次自增运算可能会导致问题,但不知道为什么Iter 1中的自增量样式无法返回正确的id值。
感谢您的任何解释或建议。
答案 0 :(得分:3)
您的代码有未定义的行为:
printf("writes %d in buff[%d]\n", buff[id], id++);
在检索id
的值并修改它之间没有序列点,编译器可以随意做任何事情。
正确的写作方式是:
printf("writes %d in buff[%d]\n", buff[id], id);
id++;
如果您使用警告进行编译,则应该得到类似的内容:
test.c:21:50: warning: operation on ‘id’ may be undefined [-Wsequence-point]
printf("writes %d in buff[%d]\n", buff[id++], id);
^
补充阅读:
答案 1 :(得分:2)
两个printf
调用都表现出未定义的行为。您有两个评估,相互之间没有排序,其中一个读取标量对象id
,另一个修改同一个对象。
答案 2 :(得分:0)
请注意,第一个循环中的两个变量的顺序错误。我猜测在printf读取buf之前发生的后增量,所以你要读取尚未输入的数组元素。比如,操作顺序(推测性地)是这样的:
write 0 to buf[0]
increment id to 1
read from buf[1]
write 1 to buf[1]
increment id to 2
read from buf[2]
然后你的数组指针中的5,越过数组的末尾,而不是阅读id
。
正如Igor所指出的,这是未定义的行为,因此根据您使用的编译器/平台,它可能会有不同的行为,并且永远不应在已发布的代码中使用。