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

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

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

C
莫回无 2019-12-22 20:12:24
将数组和数组指针传递给C中的函数之间的区别C中两个函数有什么区别?void f1(double a[]) {    //...}void f2(double *a) {    //...}如果我要在一个相当长的数组上调用这些函数,这两个函数的行为会不同,它们会占用更多的空间吗?
查看完整描述

3 回答

?
慕侠2389804

TA贡献1719条经验 获得超6个赞

首先,一些标准

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个元素的数组。



查看完整回答
反对 回复 2019-12-23
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

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

查看完整回答
反对 回复 2019-12-23
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

不,他们之间没有区别。为了测试我在Dev C ++(mingw)编译器中编写了这个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, 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

所以这个调用的两个版本没有区别,至少编译器会同等地威胁它们。



查看完整回答
反对 回复 2019-12-23
  • 3 回答
  • 0 关注
  • 376 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信