C中两个函数之间的区别是什么?C中传递数组和指针函数之间的区别C
void f1(double a[]) {
//...
}
void f2(double *a) {
//...
}
如果我打电话给一个相当长的阵列上的功能,就这两个功能不同的行为,他们将采取在堆栈上更多的空间?
C中两个函数之间的区别是什么?C中传递数组和指针函数之间的区别C
void f1(double a[]) {
//...
}
void f2(double *a) {
//...
}
如果我打电话给一个相当长的阵列上的功能,就这两个功能不同的行为,他们将采取在堆栈上更多的空间?
首先,一些standardese:
6.7.5.3功能说明符(包括原型)
...
7的参数为 '' 类型的数组 '的声明' 应调整为'合格指针 类型'',其中类型限定符(如果有的话)是在 阵列类型衍生物的[
和]
内指定的那些灰。如果关键字static
也出现在 阵列类型推导的[
和]
内,那么对于函数的每次调用,实际参数的相应值将提供对数组中第一个元素的访问,其中至少有数量为 由大小表达式指定的元素。
因此,简而言之,任何函数参数声明为T a[]
或T a[N]
被视为好像它被宣布为T *a
。
那么,为什么数组参数会被当作指针来对待呢?这里的原因:
6.3.2.1左值,数组和功能代号
...
3除了当它是sizeof
运营商或一元&
操作员的操作,或者是 字符串字面用于初始化一个数组,即具有类型“”是 转换为与类型“的表达式”指针 类型“”指向的 初始元件阵列对象,并为“ 类型的阵列”的表达式不是左翼。如果数组对象具有寄存器存储类,则行为不确定。
鉴于以下代码:
int main(void)
{
int arr[10];
foo(arr);
...
}
在呼叫到foo
,阵列表达arr
是也不sizeof
或&
的操作数,因此其类型隐含地从“10个元素的数组转换int
“到”指向int
“根据6.2.3.1/3。因此,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个要素。
区别纯粹是合成的。在C中,当数组符号用于函数参数时,它会自动转换为指针声明。
@Kaushik:虽然他们在这种情况下是相同的,请记住,他们是不一样的[在一般情况下](http://stackoverflow.com/questions/2096448/do-these-statements-about - 指针具有相同的效果) – 2011-04-06 21:55:58
@BlueRaja:是的,它是C的缺陷之一。函数参数的声明与局部变量的声明非常相似,但是存在一些细微的差别(比如作为这种数组到指针的自动变换),它们容易咬伤不知情的程序员。 – 2011-04-07 12:07:13
不,他们之间没有区别。为了测试我在开发C写本C++编写代码(MinGW的)编译:
#include <stdio.h>
void function(int* array) {
int a =5;
}
void main() {
int array[]={2,4};
function(array);
getch();
}
当我以.exe在IDA的二进制文件的两个调用版本的拆卸主要功能我得到酷似下同汇编代码:
push ebp
mov ebp, esp
sub esp, 18h
and esp, 0FFFFFFF0h
mov eax, 0
add eax, 0Fh
add eax, 0Fh
shr eax, 4
shl eax, 4
mov [ebp+var_C], eax
mov eax, [ebp+var_C]
call sub_401730
call sub_4013D0
mov [ebp+var_8], 2
mov [ebp+var_4], 4
lea eax, [ebp+var_8]
mov [esp+18h+var_18], eax
call sub_401290
call _getch
leave
retn
所以这个调用的两个版本没有区别,至少编译器会威胁它们。
对不起,但这只能证明某些版本的gcc在x86上为这两者生成了相同的程序集。正确的答案,错误的解释。 – lambdapower 2012-10-01 22:16:06
使用(至少一些较旧的)MSVC C++编译器时,由于编译器错误地在两种情况下错误地修改了函数名称(在确认它们是相同的情况下),导致链接问题,这是有区别的。请参阅“不会修复”错误报告http://connect.microsoft.com/VisualStudio/feedback/details/326874/inconsistent-name-mangling-for-functions-accepting-array-and-pointer-parameters – greggo 2013-12-12 17:02:55