为什么这个简单的C代码片段会导致无限循环?

时间:2017-07-20 06:19:01

标签: c arrays

我读了一些可能导致无限循环的代码片段(如下所列):

为什么?在我看来,我只是认为a[0]在循环中被忽略并且可能在a[10]上溢出,因为a[10]的数组索引是从0到9的C.我不明白关于循环无限的知识的本质。解释是什么?

  int main(void) {
      int a[10], i;

      for (i =1; i <= 10; i++) {
         a[i] = 0;
      }

      return 0;
   }

5 个答案:

答案 0 :(得分:5)

未定义的行为,因为您一直在尝试存储比数组大小更多的元素。

因此,请在Fred Flintstone, ADDED on January 1st 2015 By Barney Rubble 循环条件中使用i < 10而不是for。此外,i <= 10i循环初始化部分中以0而不是1开头。

C11标准说:

  

J.2未定义的行为

     

数组下标超出范围,即使对象显然也是如此   可以使用给定的下标访问(如左值表达式)   a [1] [7]给出a [4] [5])(6.5.6)中的声明。

答案 1 :(得分:1)

在你的循环中你的数组索引超出范围。只允许大小为n的数组从索引0取消引用元素到索引n-1。任何其他事情都会导致不确定的行为。

int a[10];
// a[0] <= lowest element
// a[9] <= highest element

在您的情况下,变量的内存分配可能如下所示:

a[0] | a[1] | a[2] | a[3] | a[4] | a[5] | a[6] | a[7] | a[8] | a[9] | i=a[10]

所以你的循环将执行以下内容:

i=1: a[1]=0;
i=2: a[2]=0;
i=3: a[3]=0;
i=4: a[4]=0;
i=5: a[5]=0;
i=6: a[6]=0;
i=7: a[7]=0;
i=8: a[8]=0;
i=9: a[9]=0;
i=10: a[10] = i = 0;   // <-- undefined behavior, index i will be set to 0

i=0: a[0]=0;
i=1: a[1]=0;
// [...infinite loop...]

答案 2 :(得分:0)

修改[10]会导致未定义的行为,因为数组下标超出范围。这是关于会发生什么的假设。

当我变为10时,你尝试做a[10]=0(在分配的缓冲区后写),你不知道那里存储了什么。例如,变量i可以存储在+ 10。

在这种情况下,当i到达10时,&amp; i = a + 10且[10] = 0会将i重置为0,测试条件将为真,并且循环将从i = 0继续。

等等永远。第一个循环将以i = 1开头,第二个循环将以i = 0开始。

答案 3 :(得分:-1)

您的代码段中没有任何问题。

a [10]是一个数组。

它在内存中有一个特定的位置,可以容纳10个整数。唯一的问题是指向索引。使用(0到9)或,(1到10)

我执行了你的代码,我收到了这个回复:

  

成功时间:0记忆:9296信号:0

理想情况下,当我在在线IDE上执行代码时,输​​出应为空白。请分享您在控制台上获得的输出。

答案 4 :(得分:-1)

我在代码中找不到任何编译或运行时错误。这绝对没问题。但是,您可以尝试这样

 int main () {

     int a[ 10 ];
     int i,j;

     /* Initialize elements of array a*/
     for ( i = 0; i < 10; i++ ) {
        a[ i ] = i + 20; /* Set element at location i to i + 20 */
     }

     /* Output each array element's value */
     for (j = 0; j < 10; j++ ) {
       printf("Element[%d] = %d\n", j, a[j] );
     }
     return 0;
  }

仅举一个案例,如果循环以0开头并上升到9怎么办?