-2

我正在尝试别的东西,但突然卡住了这个无限循环。请提出一个答案,并解释下面的 for 循环中发生的事情

#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

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

~

4

6 回答 6

5

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

正如您在问题中所说,解决此问题的方法是将<=for 循环的退出条件替换为<.

于 2012-10-22T11:00:26.950 回答
2

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

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

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

是的。

于 2012-10-22T10:59:40.110 回答
2

为避免轻易导致此类错误,这里有两个for在实际(本地)数组上编写循环的好规则:

  1. 迭代从索引 0 开始,因为 C 的数组是从 0 开始的。
  2. 始终使用<。从不<=
  3. 不要重复大小,让编译器使用sizeof array / sizeof *array. 注意第二项中的星号。

所以,这个循环应该是这样写的:

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

然后你就安全了。

请注意,这仅适用于大小可见的“真实”数组sizeof,如果您让数组“折叠”成指针,它将不起作用。

另请注意,这sizeof不是一个函数,因此()在这种情况下,它的参数周围不需要 s。

于 2012-10-22T11:09:55.693 回答
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;

于 2012-10-22T12:19:50.527 回答
1

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

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

于 2012-10-22T11:20:45.047 回答
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;
}
于 2012-10-22T11:00:31.843 回答