这个for循环中发生了什么

时间:2012-10-22 10:58:44

标签: c arrays for-loop

我正在尝试别的东西,但突然陷入这种无限循环。 请建议一个答案,解释下面的循环内容正在进行循环

#include<stdio.h>

int main()
{
 int x=0;
 int i;
 int array[5];
 for(i=0;i<=5;i++)
 {
  array[i]=x;
  printf("#%d value set in index %d\n",x,i);
 }

 return 0;
}

当我在=循环的条件下删除for符号时,它可以正常工作。

但是当我把它放到无限循环时,为什么? 访问数组中的额外元素(超过其限制)是未定义的行为还是什么? 任何帮助将不胜感激。 提前谢谢。

6 个答案:

答案 0 :(得分:5)

你正在向一个空间为5的数组写入6个整数。第6次写入超出了数组的范围,因此其效果是不可预测的。在您的情况下,它写入堆栈的下一个sizeof(int)字节。这是用于循环计数器i的内存,它被重置为0。

正如您在问题中所述,解决此问题的方法是用<=替换for循环的<退出条件。

答案 1 :(得分:2)

i==5时发生未定义的行为。 array具有有效索引0..4 - C中的数组从0开始。

如果用<=替换<,则迭代有效索引。

  

在数组中访问额外元素(超过其限制)是未定义的行为还是什么?

答案 2 :(得分:2)

为了避免像这样容易造成错误,这里有两个很好的规则,用于在实际(本地)数组上编写for循环:

  1. 迭代从索引0开始,因为C的数组是从0开始的。
  2. 始终使用<。从不<=
  3. 不要重复大小,让编译器使用sizeof array / sizeof *array计算它。请注意第二个术语中的星号。
  4. 所以,这个循环应该写成:

    for(i = 0; i < sizeof array / sizeof *array; i++)
    

    然后你会安全的。

    请注意,这仅适用于sizeof可见大小的“真实”数组,如果您让数组“折叠”到指针中则无法正常工作。

    另请注意,sizeof不是函数,因此在这类情况下,其参数不需要()

答案 3 :(得分:2)

为什么你进入一个无限循环,在这个特定的情况下,实际上很容易理解,看看你的堆栈上的地址:

int main( ) 
{
    int x = 0;
    int i;
    int array[5];
    printf("&x = %#x, &i = %#x, array = %#x, array+4 = %#x\n", &x, &i, array, array+4);

printf()的结果将显示变量的地址以及数组的开头和结尾:

&x = 0xbfac9cec, &i = 0xbfac9ce8, array = 0xbfac9cd4, array+4 = 0xbfac9ce4

所以按顺序,你的堆栈看起来像:

 var        address
***********************
array[0]    0xbfac9cd4
array[1]    0xbfac9cd8
array[2]    0xbfac9cdc
array[3]    0xbfac9ce0
array[4]    0xbfac9ce4
  i         0xbfac9ce8
  x         0xbfac9cec

现在你的循环正在写0-5(6个元素),你的数组中只有5个元素,所以写入第6个实际上会覆盖堆栈上的下一个东西,在这种情况下是i。 这就是这一行:

array[i]=x;

与写这篇文章相同:

i = x;

这会将0(在你的情况下)存储到i,并重新启动循环,所以你将看到它永远循环并打印“0存储到索引0”,然后“索引1”,2,3, 4然后在设置i=x;

时重新启动

答案 4 :(得分:1)

您正在尝试将6个int值存储在大小为5的数组中,这是非法的。

因此,当您尝试在数组的第6个位置写入时,您将使用值i(即0)写入变量x。 现在,在i为0的下一次迭代中,它小于for循环中指定的条件。这会导致你的循环一次又一次地运行!

答案 5 :(得分:0)

你的for循环应该从0到4,因为你的数组有5个元素

#include<stdio.h>

int main()
{
 int x=0;
 int i;
 int array[5];
 for(i=0;i<5;i++)
 {
  array[i]=x;
  printf("#%d value set in index %d\n",x,i);
 }

 return 0;
}
相关问题