我读了一些可能导致无限循环的代码片段(如下所列):
为什么?在我看来,我只是认为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;
}
答案 0 :(得分:5)
未定义的行为,因为您一直在尝试存储比数组大小更多的元素。
因此,请在Fred Flintstone, ADDED on January 1st 2015 By Barney Rubble
循环条件中使用i < 10
而不是for
。此外,i <= 10
在i
循环初始化部分中以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
怎么办?