sizeof如何知道数组的大小?

时间:2014-12-17 04:16:38

标签: c++ c arrays pointers

我的代码如下:

main() {
    int array[5] = {3,6,9,-8,1};
    printf("the size of the array is %d\n", sizeof(array));
    printf("the address of array is %p\n", array);
    printf("the address of array is %p\n", &array);
    int * x = array;
    printf("the address of x is %p\n", x);
    printf("the size of x is %d\n", 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)会有所不同?我跟踪了几个与阵列衰减相关的帖子,但对这个问题一无所知。

7 个答案:

答案 0 :(得分:14)

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

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

答案 1 :(得分:14)

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

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

当您获取数组的地址时,您将获得相同的值(即,相同的地址),就好像您只使用了数组的名称而没有获取地址一样。但是类型是不同的 - 当你明确地获取地址时,你得到的是一个类型为&#34的指针;指向类型为T"的N个项的数组的指针。这意味着(例如)当array+1指向数组的第二个元素时,&array+1指向刚好超过整个数组末尾的另一个数组。

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

在你的情况下,假设数组的大小是20,并且数组的一个元素的大小是4,如果array是0x1000,那么array+1将是{ {1}}和0x1004&array+1(0x14 = 20)。

答案 2 :(得分:9)

请注意,sizeof 是一个库函数。 sizeof

  

可用于计算的编译时一元运算符[...]   任何物体的尺寸
K& R

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

  

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

答案 3 :(得分:7)

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

数组可以包含类似数据类型的元素。数组的内存是连续的。

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

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

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

在这种情况下:

5*4 = 20

sizeof(int)sizeof(pointer)再次取决于平台。在这种情况下,您将sizeof(pointer)视为8。

答案 4 :(得分:4)

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

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

答案 5 :(得分:2)

C11:6.5.3.4(p2)

  

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

在声明中

int array[5]  

array的类型是5个int s 的数组。编译器将根据此类型确定array的大小。

答案 6 :(得分:0)

试试这个

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