C中的两个函数有什么区别?
void f1(double a[]) { //... }
void f2(double *a) { //... } 如果我要在一个相当长的数组上调用这些函数,这两个函数的行为是否会不同,它们会在堆栈上占用更多空间吗? 问题来源于stack overflow
首先,一些标准语:
6.7.5.3函数声明符(包括原型) ... 7参数声明为“ 类型数组”应调整为“ 类型的限定指针 ”,其中类型限定符(如果有)是指定的在[和]类型的数组派生。如果关键字static也出现在[和]的数组类型推导中,则对于函数的每次调用,相应实际参数的值应提供对数组第一个元素的访问,该元素的大小至少与size指定的数量相同表达。 简而言之,任何声明为T a[]或的函数参数T a[N]都将被视为声明T *a。
那么,为什么将数组参数当作声明为指针一样对待呢?原因如下:
6.3.2.1左值,数组和函数指示符 ... 3除非它是运算sizeof符或一元运算&符的操作数,或者是用于初始化数组的字符串文字,否则其类型为“ array type ' '转换为类型为“ pointer to type ” 的表达式,该表达式指向数组对象的初始元素,而不是左值。如果数组对象具有寄存器存储类,则该行为是不确定的。 给出以下代码:
int main(void) { int arr[10]; foo(arr); ... } 在对的调用中foo,数组表达式arr不是sizeof或的操作数&,因此根据6.2.3.1/3 ,其类型从“的10个元素的数组int” 隐式转换为“指向的指针int”。这样,foo将接收一个指针值,而不是一个数组值。
由于6.7.5.3/7,你可以写foo为
void foo(int a[]) // or int a[10] { ... } 但它会被解释为
void foo(int *a) { ... } 因此,两种形式是相同的。
6.7.5.3/7中的最后一句话是C99引入的,基本上意味着如果您有一个参数声明,例如
void foo(int a[static 10]) { ... } 对应的实际参数a必须是至少包含 10个元素的数组。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。