该循环如何结束,结果是否确定?

| 我找到了一些代码,并且对循环如何退出以及如何工作感到困惑。程序是否产生确定性输出? 我感到困惑的原因是:
1. `someArray` is of size 2, but clearly, the loop goes till size 3,
2. The value is deterministic and it always exits `someNumber` reaches 4
有人可以解释一下这是怎么回事吗? 当我在include \的库名称周围放置尖括号
<>
时,代码无法正确打印。
#include <stdlib.h>
#include <time.h>
#include <stdio.h>

int main() {
    int someNumber = 97;
    int someArray[2] = {0,1};
    int findTheValue;

    for (findTheValue=0; (someNumber -= someArray[findTheValue]) >0; findTheValue++) {

    }
        printf(\"The crazy value is %d\", findTheValue);
    return EXIT_SUCCESS;
}
    
已邀请:
访问数组元素超出其范围是未定义的行为。就是说,该程序可以做任何它想做的事,答复3,吃掉硬盘或花光所有的钱。换句话说,在这种情况下发生的事情完全取决于平台。它可能看起来像“确定性”,但这仅仅是因为您很幸运,也可能是因为您只是从那个地方阅读而没有写东西。 这种代码很糟糕。不要那样做。     
取决于您的编译器,
someArray[2]
是指向
findTheValue
的指针! 由于这些变量是一个接一个地声明的,因此很有可能将它们连续放置在内存中(我相信是在堆栈上)。 C并没有真正进行任何内存管理或错误检查,因此
someArray[2]
表示内存在
someArray[0] + 2 * sizeof(int)
。 因此,当
findTheValue
为0时,我们减去,然后当
findTheValue
为1时,我们减去1。当
findTheValue
为2时,我们减去
someNumber
(现在为94)并退出。 这种行为绝不能得到保证。不要依赖它! 编辑:很可能someArray [2]指向RAM中的垃圾(未指定)值。这些值可能大于93,并将导致循环退出。 EDIT2:或者
someArray[2]
someArray[3]
是大的负数,并且两者相减会导致someNumber翻转为负数。     
由于未设置(someNumber-= someArray [findTheValue]),因此退出循环。 添加调试行,您可以看到
value 0 number 97 array 0
value 1 number 96 array 1
value 2 number 1208148276 array -1208148180
正在打印出findTheValue,someNumber,someArray [findTheValue] 乍一看,这不是我期望的答案。     
检查地址:
printf(\"&someNumber =   %p\\n\", &someNumber);
printf(\"&someArray[0] = %p\\n\", &someArray[0]);
printf(\"&someArray[1] = %p\\n\", &someArray[1]);
printf(\"&findTheValue = %p\\n\", &findTheValue);
给这个输出:
&someNumber =   0xbfc78e5c
&someArray[0] = 0xbfc78e50
&someArray[1] = 0xbfc78e54
&findTheValue = 0xbfc78e58
似乎出于某种原因,编译器将数组放在堆栈区的开始,然后放在下面声明的变量,然后放在声明顺序在上面的变量。因此someArray [3]有效地指向someNumber。 我真的不知道原因,但是我在带有和不带有优化的Ubuntu 32位和Visual Studio上尝试了gcc,结果总是相似的。     

要回复问题请先登录注册