索引数组时会出现无限循环

时间:2017-01-12 15:47:15

标签: c

int main()
{
    int i;
    int vals[5];

    for (i = 0; i <= 5; i++)
    {
        vals[i] = 0;
    }
    printf("%d\n", i);
    return 0;
} 

我正在尝试从大学教程中学习C语言。他们在上面的代码中提到:

当我达到5时,for循环重置,程序再次循环,然后重复循环。

我无法理解为什么,我试图在pythontutor.com中弄清楚它给出了6(现在是C的实验)。适当的输出是什么以及为什么会出现这种情况?

3 个答案:

答案 0 :(得分:6)

C中的数组索引是基于0的。因此,如果您的数组大小为5,则索引从0到4。

循环for (i = 0; i <= 5; i++)到达索引5,它超出了数组的范围。

超出缓冲区边界是C中的未定义行为。允许任何事情发生。而你的程序完全失败,是一个可能的结果。

可能正在发生,因为数组和索引在内存中彼此相邻。因此vals[5] = 0i设置为零。从此以后,循环条件永远得到满足。

答案 1 :(得分:5)

此代码调用未定义的行为。 这当然意味着他们所说的,可能实际发生。但这很大程度上取决于许多细节。

当他们声明i将被重置时,他们会假设堆栈上的某个变量位置。 一旦执行

vals[i] = 0;

使用i==5可以实际写入存储i的位置。但另一方面,i只能保存在寄存器中或堆栈中的其他位置,您将无法获得无限循环。

答案 2 :(得分:0)

具有automatic storage class的变量(在除static variables之外的函数中创建的变量)是在C编程语言的堆栈中创建的。

程序中的变量也是在堆栈中创建的。因此,变量ivals[0]vals[1]vals[2]vals[3]vals[4]可以在堆栈中找到。

请记住:C programming language中的数组索引从0开始。如果数组的大小为n,则索引从0到(n-1)。

当您的索引变量达到for时,程序中的5循环正在尝试访问val [5]。到达数组范围之外的是C中的 UNDEFINED BEHAVIOR 。您看到的结果是可能的结果之一。由于您的堆栈中不存在vals[5],因此您可能正在访问分配给某个其他变量的内存位置,该变量可能是分配给变量i的内存位置。你甚至可以获得分段错误,如果你访问一个数组超出它的界限(正如我上面提到的,结果是未定义的。你的程序可以运行而没有任何分段错误,或者你可能得到它)。 / p>

考虑一下我创建的图片:

enter image description here

在您的情况下,数组(vals)和索引(i)可能在堆栈中彼此相邻。因此,vals[5] = 0将i重置为零,因此无限循环。