我正在尝试这个代码片段,
#include <stdio.h>
main(){
int a[2],i;
a[5] = 12;
for(i=0;i<10;i++){
printf("%d\n", a[i]);
}
return 0;
}
它给了我输出:
1053988144
32767
0
3
0
12
-1267323827
32716
0
0
为什么 a[5] 是可访问的?不应该通过运行时错误吗?
我正在尝试这个代码片段,
#include <stdio.h>
main(){
int a[2],i;
a[5] = 12;
for(i=0;i<10;i++){
printf("%d\n", a[i]);
}
return 0;
}
它给了我输出:
1053988144
32767
0
3
0
12
-1267323827
32716
0
0
为什么 a[5] 是可访问的?不应该通过运行时错误吗?
C 对数组访问没有边界检查,所以不应该。语言中没有什么可以阻止您尝试读取您可以想象的每个(虚拟)地址,尽管操作系统和/或计算机本身通常会抗议,这可能会产生某种异常。请注意,仅仅因为您“可以”(它编译并运行,似乎没有任何不良影响),并不意味着该程序是有效的或它“有效”。无效内存访问的结果是未定义的行为。
int a[2];
意思是“分配内存2 * sizeof(int)
”
a[5]
是句法糖*(a + 5)
,它指向一个内存区域a + (5 * sizeof(int))
。所以3 * sizeof(int)
过了你的数组的末尾。哪里是?谁知道?
一些语言会做边界检查,我听说一些 C 编译器也能做到这一点,但大多数都没有。为什么不做边界检查?表现。性能是首先使用 C 的主要原因。但这没关系,因为 C 程序员是优秀的程序员,永远不会超出数组的范围。(希望)
不对索引范围执行任何控制。这就是 C 的工作方式。