为了账号安全,请及时绑定邮箱和手机立即绑定

C中将数组和数组指针传递到函数中的区别

C中将数组和数组指针传递到函数中的区别

C
子衿沉夜 2019-06-26 16:20:29
C中将数组和数组指针传递到函数中的区别这两个函数在C中有什么区别?void f1(double a[]) {    //...}void f2(double *a) {    //...}如果我要调用一个相当长的数组上的函数,这两个函数的行为会有所不同吗?它们在堆栈上会占用更多的空间吗?
查看完整描述

3 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

首先,有些标准:

6.7.5.3函数声明器(包括原型)
...
7参数的声明为“数组。类型“应调整为”限定指针到类型‘,其中类型限定符(如果有的话)是在[]数组类型派生。如果关键字static也出现在[]对于数组类型派生,然后对于函数的每次调用,对应的实际参数的值应该提供对数组的第一个元素的访问,其元素至少与大小表达式指定的元素相同。

因此,简而言之,任何函数参数声明为T a[]T a[N]被处理好像它被宣布T *a.

那么,为什么数组参数被视为被声明为指针呢?原因如下:

6.3.2.1值、数组和函数指示符
...
3除非是sizeof操作员或一元&运算符,或者是用于初始化数组的字符串文字,该表达式的类型为类型“被转换为具有类型‘指针的表达式。类型“指向数组对象的初始元素,而不是lvalue。如果数组对象具有寄存器存储类,则行为未定义。

鉴于以下代码:

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个要素。


查看完整回答
反对 回复 2019-06-26
?
动漫人物

TA贡献1815条经验 获得超10个赞

这种区别纯粹是句法上的区别。在C中,当函数参数使用数组表示法时,它会自动转换为指针声明。


查看完整回答
反对 回复 2019-06-26
?
守着一只汪

TA贡献1872条经验 获得超3个赞

不,他们之间没有区别。为了进行测试,我在Dev C+(明火)编译器中编写了这个C代码:

#include <stdio.h>void function(int* array) {
     int a =5;}void main() {  
     int array[]={2,4};
     function(array);
     getch();}

当我拆开函数在IDA中调用二进制文件的两个版本的.exe中得到完全相同的汇编代码,如下所示:

push    ebp
mov     ebp, esp
sub     esp, 18hand     esp, 0FFFFFFF0hmov     eax, 0add     eax, 0Fhadd     eax, 0Fhshr     eax, 4shl     eax, 4mov     [ebp+var_C], eax
mov     eax, [ebp+var_C]call    sub_401730
call    sub_4013D0
mov     [ebp+var_8], 2mov     [ebp+var_4], 4lea     eax, [ebp+var_8]mov     [esp+18h+var_18], eax
call    sub_401290
call    _getch
leave
retn

因此,这个调用的两个版本没有区别,至少编译器对它们的威胁是相等的。


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 773 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号