问题描述
我对这个很好奇:
int main()
{
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << " - " << sizeof(a) << " - " << sizeof(*a) << std::endl;
}
退货
Length of array = 7 - 28 - 4
所以我的问题是:为什么我必须使用 (sizeof(a)/sizeof(*a))
来接收正确的大小,为什么 sizeof(*a)
返回 4
,但 sizeof(a)
返回 {{1 }}?
解决方法
sizeof(a)
返回 28
,因为数组中有 7 个元素,每个元素的长度为 4 个字节。
sizeof(*a)
返回 4
,因为 *a
取消引用数组中的第一个元素(一个整数),它是 4 个字节长。
因此,sizeof(a) / sizeof(*a) == 28/4 == 7
编辑:
您不应该养成在 C++ 中以这种方式查找数组长度的习惯。最好保留另一个变量来存储数组的长度。 sizeof
是在编译时使用固定长度数组计算的。如果您对可变长度数组调用 sizeof
,它通常会返回 8,因为这是指针的大小(在 64 位系统上)。有关这方面的更多信息,请参阅 here。
a
和 *a
的类型不同;分别为 int[7]
和 int
(忽略作为左值的可能引用)。
我们有:
-
sizeof(a[0])
=sizeof(*a)
=sizeof (int)
-
sizeof(a)
=sizeof (int[7])
=7 * sizeof (int)
-
sizeof(a)/sizeof(*a)
=std::extent
<int[7]>::value
= 7
看来,对于您的配置,sizeof(int) == 4
。
数组的名称衰减为指向第一个元素的指针。
*a == a[0]
*(1+a) == a[1]
等等。
所以,一个整数指针有 4 个字节长,就像一个 int 变量一样。
另一方面,a
数组是一个长度为7的整数数组,所以整体大小为7 * 4 = 28
a
在传递给函数、在运算符中使用或以任何方式几乎像变量一样使用时衰减为指针。 *a
指的是衰减的指针指向的内容。换句话说,a
衰减为 int*
,指向 a
中的第一个值,而 *a
是 int
,这就是为什么 {{1 }} 使用两种数据类型返回不同的大小。
通过语句 int a[7]
,您声明了一个大小为 7 的整数数组(此处只能存储 7 个整数元素)。
如果您使用语句 sizeof(a)
,您将获得 大小。您可能知道,它是 7 x 4
。 (为什么是 4?因为整数的大小是 4 个字节)。因此,如果需要得到数组的real大小(即元素个数),必须除以int
的大小。
为什么我必须使用 (sizeof(a)/sizeof(*a))
来接收正确的大小,为什么 sizeof(*a)
返回 4,而 sizeof(a)
返回 28?
要回答这个问题,您必须知道数组名称实际上是指向数组第一个元素的指针(即在这种情况下,它指向 a[0]
。)那么,什么是 {{1} }?是整数吧?您可以将 a[0]
视为 sizeof(*a)
。
由于 sizeof(int)
返回 sizeof(int)
,因此 4
也将返回。
你得到 7(正确答案)的原因是:
sizeof(*a)
,
sizeof(a) = 7 * 4
,因此
sizeof(*a) = 4
。