C中的自增量返回0?

时间:2014-03-24 02:11:39

标签: c

基本上这是一个将值写入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值。

感谢您的任何解释或建议。

3 个答案:

答案 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所指出的,这是未定义的行为,因此根据您使用的编译器/平台,它可能会有不同的行为,并且永远不应在已发布的代码中使用。