这个数组的大小为 1,但我可以用这些值初始化它,然后我甚至可以在实例化数组后设置更多值,它仍然有效。我不明白为什么。
int array[1] = {12,2,12,12,12,31};
printf("%d\n",array[1]);
printf("%d\n",array[0]);
array[1] = 1;
array[8] = 3;
printf("%d\n",array[1]);// 1 It works. Why?
printf("%d\n",array[8]);// 3 It works. Why?
在 C 语言中,数组没有内置边界检查。访问超出声明的数组边界的内容不会立即导致程序崩溃。相反,这被称为未定义行为。未定义行为意味着标准没有定义必须发生什么,因此程序可能看起来“正常”,或者可能崩溃或损坏内存。
当你这样做时:
array[1] = 1;
array[8] = 3;
您正在写入数组分配空间之外的内存区域。编译器不会阻止您这样做,并且如果这些内存区域对于程序的运行并不重要(或者如果您很幸运),您的程序可能看起来运行正常。但这只是运气好,不可预测的行为随时可能发生。
正如其他人指出的那样,您的编译器可能会发出警告。
直接回答您,正在发生的事情是,您正在定义一个与一个元素的数组名称“array”相关联的符号,然后程序将从地址 &a[0] 开始的初始化值与关联的数组大小无关。
这意味着 sizeof(array) 仍应返回 1,并且任何访问索引大于 0 的数组元素的操作都将生成编译器警告。
可能的话,如果您在具有指定值的数组后定义另一个 int 变量,则数组初始值设定项的第二个元素将在内存中被前者替换。
数组在 C 中实际上并不存在。它们只是进程内存空间的区域。变量指向第一个地址,
a[n]
语法是查找n
之后的位置a
。数组不会记住它的长度,也不会强制你只能访问它所拥有的内存。你只是在末尾的任意内存上进行读取/写入。
如果这是进程内的有效内存,那么您将覆盖其他一些数据。如果不是,操作系统将通过分段错误 (SIGSEGV) 终止您的进程。