最近我自己开始学习 C ,所以可能会有点新手问题。 我编译了以下命令:
#include <stdio.h>
int main()
{
int arr[5]={0};
int arr2[5]={0};
printf("%d\n",arr[5]); //here output: 2130567168
printf("%d\n",arr2[5]); //here output: 0
return 0;
}
任何人都可以解释不同产出的原因吗?
答案 0 :(得分:3)
两个printf
都会产生未定义的行为,因为它们正在访问超过相应数组末尾的元素。 C数组索引的有效范围是length-1
为零,因此程序中的两个数组都是0..4(含)。
在索引5处访问元素超出了数组的末尾,因此不同的编译器可以产生不同的行为,从打印垃圾到崩溃。
答案 1 :(得分:2)
您正在访问超出声明范围的数据。已声明为arr[5]
的数组的索引范围为0 ... 4,但您要访问arr [5],既未定义也未分配。因此,您可以根据内存的值来获得随机答案&#34; cell&#34;你想访问,在这种情况下是0和另一个号码。
答案 2 :(得分:2)
这是未定义的行为。 C不对数组执行bound checking。
答案 3 :(得分:2)
将来,请在编译器上启用警告。例如,对于GCC,这将是-Wall
。
main.cpp:7:29: warning: array subscript is above array bounds [-Warray-bounds]
printf("%d\n",arr[5]); //here output: 2130567168
^
main.cpp:8:30: warning: array subscript is above array bounds [-Warray-bounds]
printf("%d\n",arr2[5]); //here output: 0
请注意,C标准表明这是未定义的行为:
§J.2
1在以下情况下,行为未定义:
- 数组下标超出范围,即使某个对象显然也是如此 可以使用给定的下标访问(如左值表达式) a [1] [7]给出a [4] [5])(6.5.6)中的声明。
接受关于undefined behavior的常规讲座。
答案 4 :(得分:0)
C中此代码的行为在C规范(Online draft for c specs)的6.7.8.21节中描述:对于没有指定值的元素,编译器将指针初始化为NULL和算术类型为零(并递归地将其应用于聚合)。
请参考以上文件了解。我也不是直接在这里发布答案因为你是新手,因为我不想用勺子喂你。快乐学习。 。