将数组和数组指针传递给C中的函数之间的区别

将数组和数组指针传递给C中的函数之间的区别

C中两个函数有什么区别?

void f1(double a[]) {
   //...}void f2(double *a) {
   //...}

如果我要在一个相当长的数组上调用这些函数,这两个函数的行为会不同,它们会占用更多的空间吗?


莫回无
浏览 377回答 3
3回答

慕侠2389804

首先,一些标准: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或的操作数&,因此根据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.99.5.3/7中的最后一句是用C99引入的,基本上意味着如果你有一个参数声明void foo(int a[static 10]){   ...}对应的实际参数a必须是一个至少包含 10个元素的数组。

小唯快跑啊

差异纯粹是语法上的。在C中,当数组表示法用于函数参数时,它会自动转换为指针声明。

犯罪嫌疑人X

不,他们之间没有区别。为了测试我在Dev C ++(mingw)编译器中编写了这个C代码:#include <stdio.h>void function(int* array) {&nbsp; &nbsp; &nbsp;int a =5;}void main() {&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;int array[]={2,4};&nbsp; &nbsp; &nbsp;function(array);&nbsp; &nbsp; &nbsp;getch();}当我在IDA中的两个调用版本的二进制文件的.exe中反汇编主函数时,我得到完全相同的汇编代码,如下所示:push&nbsp; &nbsp; ebpmov&nbsp; &nbsp; &nbsp;ebp, espsub&nbsp; &nbsp; &nbsp;esp, 18hand&nbsp; &nbsp; &nbsp;esp, 0FFFFFFF0hmov&nbsp; &nbsp; &nbsp;eax, 0add&nbsp; &nbsp; &nbsp;eax, 0Fhadd&nbsp; &nbsp; &nbsp;eax, 0Fhshr&nbsp; &nbsp; &nbsp;eax, 4shl&nbsp; &nbsp; &nbsp;eax, 4mov&nbsp; &nbsp; &nbsp;[ebp+var_C], eaxmov&nbsp; &nbsp; &nbsp;eax, [ebp+var_C]call&nbsp; &nbsp; sub_401730call&nbsp; &nbsp; sub_4013D0mov&nbsp; &nbsp; &nbsp;[ebp+var_8], 2mov&nbsp; &nbsp; &nbsp;[ebp+var_4], 4lea&nbsp; &nbsp; &nbsp;eax, [ebp+var_8]mov&nbsp; &nbsp; &nbsp;[esp+18h+var_18], eaxcall&nbsp; &nbsp; sub_401290call&nbsp; &nbsp; _getchleaveretn所以这个调用的两个版本没有区别,至少编译器会同等地威胁它们。
打开App,查看更多内容
随时随地看视频慕课网APP