我对某事有些困惑:
如果我有一个结构数组:table
,长度为X
,并且我想访问它的最后一个元素:table[X]
或table[X-1]
。如果是table[X-1]
,则table[X]
包含什么?
答案 0 :(得分:1)
C中数组的索引从零开始,即第一个元素在table[0]
中,第二个元素在table[1]
中,第三个元素在table[2]
中……最后一个在在table[X-1]
中。
table[X]
在数组范围之外。 C没有边界检查,因此编译器允许访问它,但这是未定义的行为,即您永远不会知道会发生什么。读取它可能会浪费内存或导致诸如分段错误之类的操作系统异常。
答案 1 :(得分:0)
结构在内存中的工作方式与该实例中整数或其他一些基本数据类型的工作方式相同。您的数组将仅由sizeof(struct)而不是sizeof(基本数据类型)分隔。
它仍然从0开始,到X-1结束。数组的类型通常只定义了两件事:
每个索引的字节数,以及如何处理数据。
为大小为3的数组成像,该结构包含5个字节的数据。您的数组将设置如下:
-----|-----|-----|????|
s1 |s2 |s3 |????|
仅仅因为它存在,并不意味着我们的程序知道它是什么。第四个[3]索引(????)将是超出数组范围的索引。但是有可能在这里获得一些有意义的价值,但可能性很小。在大多数情况下,它要么是垃圾,要么会导致错误。
答案 2 :(得分:0)
对于任何类型的数组,答案都是相同的。如果你有一个大小
X
:
int a[5];
struct my_struct ms[10];
...
您可以指定该数组中元素的数量。因为第一个元素是元素0,所以最后一个元素始终是X - 1
。
如果您尝试访问元素a[X]
,则会得到undefined behavior。
答案 3 :(得分:0)
C中的数组使用零索引,这意味着它们以0
开头并以n-1
结尾。不要与数组声明相混淆,在数组声明中,您可以写出以项目数表示的大小。访问数组并声明一个数组的语法看起来很相似,这就是为什么这会使初学者感到困惑的原因。
示例:
int main (void)
{
int array[5]; // allocate an array with 5 elements
array[0] = 0; // access first element
array[4] = 0; // access last element (index 4)
array[5] = 0; // BAD, accessing the array out of bounds: index 5 gives item number 6
}
这就是为什么用C编写循环的规范方法是这样的:
for(int i=0; i<n; i++)
其中n
是数组的大小,迭代器i
的值将从0
到n-1
。