大小如何知道数组的大小

How does sizeof know the size of array?

本文关键字:数组 何知道      更新时间:2023-10-16

我有如下代码:

main() {
    int array[5] = {3,6,9,-8,1};
    printf("the size of the array is %dn", sizeof(array));
    printf("the address of array is %pn", array);
    printf("the address of array is %pn", &array);
    int * x = array;
    printf("the address of x is %pn", x);
    printf("the size of x is %dn", sizeof(x));
}

输出为

the size of the array is 20
the address of array is 0x7fff02309560
the address of array is 0x7fff02309560
the address of x is 0x7fff02309560
the size of x is 8

我知道变量 array 将被视为指向数组第一个元素的指针,因此我知道 x 的大小为 8。但我不知道为什么数组的大小是 20。它不应该是 8(在 64 位机器中(吗?

此外,程序如何知道它是 20?据我所知,在 C 中它不存储元素的数量。为什么sizeof(array)sizeof(x)不同?我跟踪了几篇与数组衰减有关的帖子,但对这个问题一无所知。

在大多数情况下

,数组的名称衰减为指向数组第一个元素的指针。不过,该规则有几个例外。两个最重要的例子是当数组名用作sizeof运算符或address-of运算符(&(的操作数时。在这些情况下,数组的名称仍然是整个数组的标识符。

对于非 VLA 数组,这意味着数组的大小可以静态确定(在编译时(,表达式的结果将是数组的大小(以字节为单位(,而不是指针的大小。

当您获取数组

的地址时,您将获得相同的值(即相同的地址(,就好像您只使用数组的名称而不获取地址一样。不过,类型是不同的 - 当你显式获取地址时,你得到的是一个类型的指针"指向 N 个类型 T 的项目数组"的指针。这意味着(例如(虽然array+1指向数组的第二个元素,但&array+1指向整个数组末尾之后的另一个数组。

假设数组至少包含两个项目,*(array+1)将引用数组的第二个元素。无论数组大小如何,&array+1都会生成超过数组末尾的地址,因此尝试取消引用该地址会产生未定义的行为。

在您的情况下,假设数组的大小为 20,数组中一个元素的大小为 4,如果array是,比如说,0x1000,那么array+1将是0x1004的,&array+1将是0x1014 (0x14 = 20(。

数组具有静态长度,因此可以在编译时确定。编译器知道sizeof(int) = 4和静态数组长度 [5]。4 * 5 = 20

编辑:您的编译器 int 可能是 32 位,但寻址为 64 位。这就是sizeof(pointer)返回 8 的原因。

请注意,sizeof 不是库函数。 sizeof

一个编译时一元运算符 [...],可用于计算 任何物体
的大小 K&R

所以sizeof不知道数组有多大,编译器知道数组有多大,根据定义

当应用于数组时,结果是总字节数 在数组中。
K&R

指针和数组是 2 种不同的数据类型。

数组可以保存类似数据类型的元素。阵列的内存是连续的。

指针用于指向某个有效的内存位置。

sizeof(type)为您提供所传递类型的字节数。

现在,如果您传递数组,那么编译器就知道这是一个数组和其中的元素数量,它只是将许多元素与相应的数据类型大小值相乘。

在这种情况下:

5*4 = 20

同样,sizeof(int)sizeof(pointer)取决于平台。在本例中,您看到sizeof(pointer)为 8。

不,数组不会作为sizeof运算符的操作数衰减。这是数组不衰减的少数几个地方之一。如果计算机上的int为 4 个字节,则数组的总字节数应为 20 (4 * 5(。我们甚至不需要对象来测试这一点。

sizeof(int[5]) // 20
sizeof(int*)   // 8 on a 64-bit machine

C11: 6.5.3.4 (p2(

sizeof运算符产生其操作数的大小(以字节为单位(,这可能是 表达式或类型的括号名称。大小由类型确定 操作数。[...]

在声明中

int array[5]  

array的类型是 5 int 的数组。编译器将从此类型确定array的大小。

试试这个

int x = sizeof(array)/sizeof(int);
printf("the size of the array is %dn", x);