C 中 Sizeof 的行为

Posted

技术标签:

【中文标题】C 中 Sizeof 的行为【英文标题】:Behaviour of Sizeof in C 【发布时间】:2011-07-25 08:34:57 【问题描述】:

我了解到,当我们将数组名传递给 sizeof 时,数组名不会衰减为指向基地址的指针。下面的代码通过给出答案 10 来验证这一事实。

#include <stdio.h> 

int main()  
    int arr[10];  
    printf("Size of array is %d" , sizeof(arr)/sizeof(int));  
    return 0;  

但是当我运行下面的代码时,答案是1。不管一个维度是否写在原型中,答案都是1。为什么会这样?

#include <stdio.h>

void dimension(int arr[])  
    printf("Sizof array is %d" , sizeof(arr)/sizeof(int));  



int main()  
    int arr[10];  
    dimension(arr);  
    return 0;  
  

【问题讨论】:

标准规定函数参数中的数组名将被视为指针。所以int arr[] 将是int *arrint arr[][10] 将是int (*p)[10](指针的剩余大小)。顺便说一句:sizeof(arr)/sizeof(arr[0])更好,当你改变arr的类型时,你就不用修改这个地方了。 @Stan:我认为应该是一个答案。 它产生 1 是因为您在 sizeof(void *) == sizeof(int); 的 32 位环境中工作。在 64 位环境中,它通常会产生 2,因为指针是 8 个字节,但 int 仍然是 4 个字节。 Sizeof an array in the C programming language? 的可能重复项 【参考方案1】:

这个签名

void dimension(int arr[])

绝对等价于

void dimension(int *arr)

另见Question 6.4

【讨论】:

【参考方案2】:

因为你传递了一个未知大小的数组,它在这个上下文中相当于一个指针。 sizeof编译时计算,而不是运行时。

【讨论】:

除了 C99 中的可变长度数组 (VLA),sizeof 的工作方式与您所说的一样。【参考方案3】:

当数组传递给函数时,它是作为指针传递的,而不是数组,所以sizeof(arr)会返回sizeof(int *)

【讨论】:

它不是 x64 上 int 的大小 @unkulunkulu - 这取决于,这就是我经常说的原因。 我没有注意到“通常”这个词:) 无论如何,如果 x64 不正确,你不能说“通常”:D “经常”可能是更合适的替代品,我猜。但我只是主张删除括号中的部分:)【参考方案4】:

void dimension(int arr[])  
    printf("Sizof array is %d" , sizeof(arr)/sizeof(int));  

arr[] 衰减为一个指针,因此你有相当于

printf("Sizof array is %d" , sizeof(int*)/sizeof(int));

因为在您的平台sizeof(int*) == sizeof(int) 上,您会收到1 作为结果。

但请注意,对于可变长度数组,sizeof 成为运行时操作:

int main () 
    int i = ...;
    int x[i];
    printf("number of elements: %d", sizeof (x) / size(*x));

【讨论】:

【参考方案5】:

数组作为函数参数 do 衰减为指针。由于这发生在 sizeof() 被调用之前,你无法阻止它。

想一想:如果可以传递任何大小的数组并且没有额外的信息可用,那么 sizeof() 怎么知道数组的大小?在您的设置中,您会得到 sizeof(pointer),它的大小似乎与 int 相同。

【讨论】:

【参考方案6】:

因为 arr 是一个指针,它是一个整数。

【讨论】:

【参考方案7】:

因为你传递了一个未知大小的数组。

【讨论】:

您需要提供比“因为您传递一个未知大小的数组”更多的解释才能获得声誉。答案的核心基本正确,但对评分的帮助不够。

以上是关于C 中 Sizeof 的行为的主要内容,如果未能解决你的问题,请参考以下文章

C中memset的行为[重复]

关于 sizeof 溢出 size_t 的 C 标准

C99 语言中具有未命名成员的结构的正确行为是啥?

sizeof() 运算符的行为

sizeof()运算符的行为

混淆简单C程序的缓存行为