C++ sizeof如何知道数组的大小?
我有以下代码:C++ sizeof如何知道数组的大小?,c++,c,arrays,pointers,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("
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)
是不同的?我跟踪了几篇关于数组衰减的文章,但对这个问题一无所知。您的数组具有静态长度,因此可以在编译时确定。编译器知道sizeof(int)=4
和静态数组长度[5]。4*5=20
编辑:您的编译器int可能是32位,但寻址64位。这就是为什么
sizeof(pointer)
返回8。指针和数组是两种不同的数据类型
数组可以保存类似数据类型的元素。数组的内存是连续的
指针用于指向某个有效的内存位置
sizeof(type)
提供所传递类型的字节数
现在,如果您传递数组,那么编译器知道这是一个数组和其中的元素数,它只是将这些元素与相应的数据类型大小值相乘
在这种情况下:
5*4 = 20
同样地,
sizeof(int)
或sizeof(指针)
依赖于平台。在本例中,您将sizeof(pointer)
视为8。否,数组不会作为sizeof
运算符的操作数衰减。这是为数不多的阵列不会衰减的地方之一。如果计算机上的int
为4字节,则数组的总字节数应为20(4*5)。我们甚至不需要一个物体来测试这个
sizeof(int[5]) // 20
sizeof(int*) // 8 on a 64-bit machine
在大多数情况下,数组的名称衰减为指向数组第一个元素的指针。不过,这条规则有几个例外。当数组名用作
sizeof
运算符的操作数或运算符的地址(&
)时,这两种情况最为重要。在这些情况下,数组的名称仍然是整个数组的标识符
对于非VLA数组,这意味着可以静态地(在编译时)确定数组的大小,表达式的结果将是数组的大小(以字节为单位),而不是指针的大小
当您获取数组的地址时,您会得到相同的值(即相同的地址),就好像您只是使用了数组的名称而没有获取地址一样。但类型不同——当显式获取地址时,得到的是一个类型为“指向T型N项数组的指针”的指针。这意味着(例如)当array+1
指向数组的第二个元素时,&array+1
指向刚好超过整个数组末尾的另一个数组
假设数组中至少有两个项,*(array+1)
将引用数组的第二个元素。无论数组大小如何,&array+1
都会产生一个超过数组末尾的地址,因此尝试取消引用该地址会产生未定义的行为
在您的例子中,假设数组的大小是20,数组中一个元素的大小是4,如果数组是0x1000,那么数组+1
将是0x1004
,数组+1
将是0x1014
(0x14=20)。请注意sizeof
是而不是库函数sizeof
为
编译时一元运算符[…],可用于计算
任何对象的大小
K&R
因此sizeof
不知道数组有多大,编译器知道数组有多大,根据定义
应用于数组时,结果是总字节数
在数组中。
K&R
试试这个
int x = sizeof(array)/sizeof(int);
printf("the size of the array is %d\n", x);
C11:6.5.3.4(p2)
sizeof
运算符生成其操作数的大小(以字节为单位),该操作数可以是
表达式或类型的括号名称大小由类型决定
操作数。[……]
在宣言中
int array[5]
array
的类型是5int
s的数组。编译器将根据此类型确定数组的大小 编译器知道数组元素有多大,以及数组中有多少个元素,因此它可以将这两个元素相乘,得到sizeof
的结果。了解这一点是编译器的工作。相关:公认答案的前3个主题相当广泛地解释了指针和数组之间的区别。检查这个问题数组不是指向其第一个元素的指针-它有时会自动转换为一个。您可能错过的关键点:尽管它的外观,sizeof
不是函数,而是编译时运算符。只有编译器需要知道答案,所以信息没有“存储”在程序中并不重要。