首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C++的函数原型中使用显式长度定义sizeof()数组

在C++的函数原型中使用显式长度定义sizeof()数组
EN

Stack Overflow用户
提问于 2019-12-20 01:55:58
回答 2查看 182关注 0票数 0

今天,我在使用C语言时遇到了一个奇怪的问题,我无法理解背后的原因。

如果我有一个这样的函数(假设32位架构):

代码语言:javascript
复制
void printSize(char array[6]) {
    printf("%zd\n", sizeof array);
}

我将返回4,这是指针的大小。我期望得到6,这是在函数原型中显式声明的大小。

我知道数组是通过引用传递的,底层类型是一个指针。我假设将数组的长度放在原型中将为编译器提供返回6所需的信息。

为什么C要这样做?此外,如果编译器甚至不能执行sizeof(),返回该大小,那么在原型中放置一个大小的意义是什么?

EN

回答 2

Stack Overflow用户

发布于 2019-12-20 02:08:45

您观察到的行为是由C standard强制执行的。第6.7.6.3p7节关于“函数声明符”的声明:

将参数声明为‘’类型‘’的数组应调整为‘’指向类型‘’的限定指针‘’,其中类型限定符(如果有)是在和数组类型派生中指定的那些限定符。如果关键字static也出现在数组类型派生的和中,则对于函数的每次调用,相应的实际参数的值应提供对数组的第一个元素的访问,该元素的数量至少与size表达式指定的元素数量相同。

所以编译器这样做的原因是因为标准规定他们必须这样做。此外,从实用的角度来看,这意味着您不能将实际的指针传递给这样的函数。考虑将一个数组传递给一个参数类型为int *的函数,然后再传递给一个参数类型为int [5]的函数,或者一个动态分配的数组,即int *arr = malloc(5 * sizeof(int));

另外,请注意,这只适用于多维数组的第一个维度。这意味着:

代码语言:javascript
复制
void foo(int arr[4][5])

等同于

代码语言:javascript
复制
void foo(int (*arr)[5])

但不是:

代码语言:javascript
复制
void foo(int **arr)
票数 1
EN

Stack Overflow用户

发布于 2019-12-20 02:09:30

数组不是“按引用传递”的。C中没有任何东西是“通过引用传递”的。所有的东西都是通过值传递的。

当数组作为参数“传递”给函数时,它会衰减为指向数组第一个元素的指针。

因此,sizeof array返回4 (字节),因为这就是你的实现中指针的大小。

允许您声明数组参数大小的功能主要用于文档。如果你看到一个函数原型,比如void printSize(char array[6]);,你可以假设这个函数只会访问数组的第一个6元素,尽管这个函数不需要严格遵守这一点(如果不严格遵守,编译器也不会抱怨)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59414711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档