数组可以有尾部填充吗?[duplicate]

ruyhziif  于 2023-01-01  发布在  其他
关注(0)|答案(1)|浏览(114)
    • 此问题在此处已有答案**:

Does the C standard require the size of an array of n elements to be n times the size of an element?(2个答案)
昨天关门了。
给定一个测验问题"以下函数返回的值是什么:"。

size_t f(int *a[2][3][4]) {
  return sizeof(*a);
}

答案sizeof(int *) * 3 * 4正确吗?我的意思是:ISO C标准是否保证了以下平等性?

sizeof(int *) * 3 * 4 == sizeof(int*[3][4])

我广泛的搜索了标准,得到了和this问题的被问者相同的结论,除了他们的例子和接受的答案都是关于数组的数组,但是数组的元素之间不能有填充。
我的问题是,不管为什么,一个数组会有尾部字节破坏上面提到的相等性吗?
更新:询问[2]到哪里去了。因为a是函数的参数,所以它的类型实际上是int *(*)[3][4]。参见6.7.6.3p7

gtlvzcf8

gtlvzcf81#

根据C标准,数组的大小等于数组中元素的数量乘以每个元素的大小。
在f()函数的情况下,*a的大小等于sizeof(int*) * 3 * 4,因为*a的类型是int*[3][4]int*[3][4]是3个4 int* 元素数组的数组。
该标准没有指定数组元素之间的任何填充,因此可以保证sizeof(int *) * 3 * 4 == sizeof(int*[3][4])相等。
值得注意的是,该标准确实允许在结构成员之间以及结构末尾进行填充,并且由于填充,结构的大小可能大于其成员大小之和,但这不适用于数组。
更新:指出[2]从OP问题中消失。
数组的大小由数组中元素的数量和每个元素的大小决定。在int*[2][3][4]的情况下,数组的大小等于2 * 3 * 4 * sizeof(int*),因为有2个数组,每个数组3个,每个数组4个int* 元素。
int*[3][4]之类的类型使用sizeof运算符时,它将返回该类型的大小,该大小等于3 * 4 * sizeof(int*)。外部数组(int*[2][3][4])的大小不包括在此计算中,因为*a的类型为int*[3][4],而不是int*[2][3][4]
换句话说,sizeof(*a)等价于sizeof(int*[3][4]),而不是sizeof(int*[2][3][4])
sizeof运算符的行为和确定数组大小的方式在6.5.3.4ISO C标准的www.example.com部分中指定。
以下是标准中的相关文本:
sizeof运算符生成其操作数的大小(以字节为单位),操作数可以是表达式或带括号的类型名称。大小由操作数的类型确定。结果是整数。如果操作数的类型是可变长度数组类型,则计算操作数;否则,不计算操作数,结果是整数常量。
结构体或联合体的大小是其成员大小的总和,〉包括任何填充。
这意味着数组的大小等于数组中的元素数乘以每个元素的大小,并且sizeof运算符返回它所应用到的类型的大小。
更多信息也可以在这里找到:https://en.cppreference.com/w/cpp/language/sizeof

相关问题