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

为什么这个简单的C代码片段会导致无限循环?,c,arrays,C,Arrays,我阅读了一些可能导致无限循环的代码片段(如下所列): 为什么会这样?在我看来,我只是认为a[0]在循环中被忽略了,可能会在a[10]上溢出,因为a[10]的数组索引在C中是从0到9。我不理解循环无限知识的本质。原因是什么 int main(void) { int a[10], i; for (i =1; i <= 10; i++) { a[i] = 0; } return 0; } int main(无效){

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

为什么会这样?在我看来,我只是认为
a[0]
在循环中被忽略了,可能会在
a[10]
上溢出,因为
a[10]
的数组索引在C中是从0到9。我不理解循环无限知识的本质。原因是什么

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

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

      return 0;
   }
int main(无效){
INTA[10],i;

对于(i=1;i,代码片段中没有任何问题

[10]是一个数组

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

我执行了你的代码,得到了这样的回应:

成功时间:0内存:9296信号:0


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

修改[10]会导致未定义的行为,因为您执行的数组下标超出了范围。下面是一个假设

当我变为10时,您尝试执行
a[10]=0
(在分配的缓冲区后写入),您无法知道存储在那里的内容。例如,变量
i
可能存储在+10处

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


一直如此。第一个循环将以
i=1
开始,第二个循环和下一个循环将以
i=0
开始。这是未定义的行为,因为您一直在尝试存储比数组大小更多的元素


因此,在
for
循环条件中使用
i<10
,而不是
i我实际上没有在您的代码中发现任何编译或运行时错误。这是绝对正确的。但是,您可以这样尝试

 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;
  }
int main(){
INTA[10];
int i,j;
/*初始化数组a的元素*/
对于(i=0;i<10;i++){
a[i]=i+20;/*将位置i处的元素设置为i+20*/
}
/*输出每个数组元素的值*/
对于(j=0;j<10;j++){
printf(“元素[%d]=%d\n”,j,a[j]);
}
返回0;
}

举一个例子,如果循环从
0
开始,然后上升到
9

在循环中,您的数组索引超出范围。仅允许大小为
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...]
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;//
i
i<10
。您的数组索引溢出,因此程序的行为未定义。您的数组从索引0到9,计数从0开始。这意味着未定义的行为可能导致无限循环,对吗?未定义的行为可能导致任何事情。在这种情况下,
a[10]
可能与
i
的内存位置相同。但这只是猜测。它是未定义的,所以只需解决编写定义良好的代码的问题。可能发生了什么,但请明确这只是一个假设——编译器可以为变量选择任何内存位置。@FelixPalmen是的,我写了一个关于什么是ha的假设在他的情况下出现。@alinsoar是的,您的回答让我完全清楚混淆的地方。@W.Costanza要完全确定它发生在您的编译器上,请尝试打印值
&i-(a+10)
如果它是零,那么这就是它正在发生的事情。抱歉,但是这个答案是完全错误的。你应该重写它或者删除它。不,OP的代码一点也不好。确实没有编译错误,并且有可能不会有任何运行时错误,但是OP的代码包含UB,这不是好的,但是
i
是好的未在循环内部初始化,并且当
a[10]=0
之后
i
未使用
a[10]
值初始化,即
0
此处
a[10]=0
是未定义的行为,因此OP的代码不是很好。
a[10]
未定义,但循环直到
a[10]才会迭代
。如果
i
从0开始,循环在9后终止,并迭代到
9
。使用
1=0和
启动循环,重要的是数组索引不会超出其有效范围。因此只有
i您不应该猜测未定义行为的基本原理。它只是未定义而已。@willys i agr但问题是,为什么这个代码片段会导致无限循环,而不是如何让代码工作。所以我做了一个猜测,以提供一个令人满意的答案。