当前位置:首页 > 工业控制 > 电子设计自动化
[导读]  作者:王姗姗,华清远见嵌入式学院讲师。 请看下面的程序: #include <stdio.h> void func1(int arr[]) { printf("%d\\n",sizeof(arr)); arr=arr+1; printf("%d\\n",*arr); } void func2(int *arr) { printf("%d\\n"

  作者:王姗姗,华清远见嵌入式学院讲师。

请看下面的程序:

#include <stdio.h>

void func1(int arr[])

{

printf("%dn",sizeof(arr));

arr=arr+1;

printf("%dn",*arr);

}

void func2(int *arr)

{

printf("%dn",sizeof(arr));

arr=arr+1;

printf("%dn",*arr);

}

int main()

{

int a[10]={1,2,3,4,5};

int *b=a;

printf("%dn",sizeof(a));

func1(a);

func2(a);

printf("%dn",sizeof(b));

func1(b);

func2(b);

//a=a+1;

printf("%dn",*a);

b=b+1;

printf("%dn",*a);

return 0;

}

为了说明问题,我写了一个简单的测试程序,在主函数中定义了一个a数组,并定义了一个b指针指向该数组的首地址。显然a=a+1是不能通过编译的,因为作为数组而言,a是地址常量,一旦定义是不允许指向其他地址的。

那么作为b,其仅仅是一个指针变量,里面存放的是a数组的首地址,故可以执行b=b+1,这样使得b指向a+1,也就是a数组中的a[1]。

下面问题就来了,我们该如何将一个数组作为形参传递给函数,也就是说若有一个实参数组,想在函数中改变此数组中的元素的值,我们该如何处理?

数组作为形参,和接受它的实参有以下的关系:

1. 形参和实参都是数组名。

2. 实参用数组,形参用指针变量.

3. 实参、形参都用指针变量。

4. 实参为指针变量,形参为数组名。

在上述的例子中我们来进一步的讲解。

首先来看结果:

40//sizeof(a)

4//func1(a)

2//arr=arr+1

4//func2(a)

2//arr=arr+1

4//sizeof(b)

4//func1(b)

2// arr=arr+1

4//func2(b)

2// arr=arr+1

1// a

1//b=b+1;

在C语言中,数组名是当作指针来处理的。更确切的说,数组名就是指向数组首元素地址的指针,数组索引就是距数组首元素地址的偏移量。理解这一点很重要,很多数组应用的问题就是有此而起的。这也就是为什么C语言中的数组是从0开始计数,因为这样它的索引就比较好对应到偏移量上。在C语言中,编译过程中遇到有数组名的表达式,都会把数组名替换成指针来处理;编译器甚至无法区分a[4]和4[a]的区别。

我们在题中定义了

int a[10];

int *b;

这两者并不等价,第一句话声明了数组a,并定义了这个数组,它有10个int型元素,sizeof(a)将得到整个数组所占的内存大小,是40;第二句话只是声明并定义了一个int型的指针,sizeof(b)将得到这个指针所占的内存大小,是4。所以说,虽然数组名在表达式中一般会当作指针来处理,但是数组名和指针还是有差距的,最起码有a==&a[0]但是sizeof(a)!=sizeof(a[0])。

并且在ANSI C标准中,也明文规定:在函数参数的声明中,数组名可以当作指向该数组第一个元素的指针。所以,下面的几种书写形式是等效的:

void func1(int arr[]){}

void func2(int *arr){}

对于第一种还可以写成void func1(int arr[100]){},在形参中其实不需要指定数组的大小,因为其实在这几个函数在函数调用时传入的只是一个该数组的指针,想要确定几行几列的话还需要另外定义参数进行传入.如果在使用该指针的过程中不清楚原数组的范围,指针很容易就越界,内存也就溢出了。

当用数组名作函数参数时,形参数组就可以从实参数组那里得到起始地址后,形参数组就和实参数组共占同一段内存单元,从而在调用函数期间,如果改变了形参数组的值,也就该变了实参数组的值。

最后要补充一点,也就是上次我们学员问我的一个问题,作为形参int arr[]和int *arr有什么区别。在本质上,我们看通过程序,貌似真的没有区别,虽然arr[]是作为数组传递进去,但是我们也可以修改arr的指向,而作为实参的数组的a却不能使其加一。我们都知道函数之间的参数传递有:复制传递方式、地址传递方式、全局变量。

那么姑且就将void func1(int arr[])最为函数按复制传递的方式,而void func2(int *arr)作为其地址传递的方式。而复制传递方式与数组的指针传递方式是完全相同,只是形参的说明形式不同而已。调用函数将实参数组传递给被调用函数形参,形参接收是实参的地址。不论哪种方式,被调用函数里对形参数组的操作都会影响调用函数里的实参数组。

“本文由华清远见http://www.embedu.org/index.htm提供”



来源:华清远见0次

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

特朗普集团近日取消了其新推出的T1智能手机“将在美国制造”的宣传标语,此举源于外界对这款手机能否以当前定价在美国本土生产的质疑。

关键字: 特朗普 苹果 AI

美国总统特朗普在公开场合表示,他已要求苹果公司CEO蒂姆·库克停止在印度建厂,矛头直指该公司生产多元化的计划。

关键字: 特朗普 苹果 AI

4月10日消息,据媒体报道,美国总统特朗普宣布,美国对部分贸易伙伴暂停90天执行新关税政策,同时对中国的关税提高到125%,该消息公布后苹果股价飙升了15%。这次反弹使苹果市值增加了4000多亿美元,目前苹果市值接近3万...

关键字: 特朗普 AI 人工智能 特斯拉

3月25日消息,据报道,当地时间3月20日,美国总统特朗普在社交媒体平台“真实社交”上发文写道:“那些被抓到破坏特斯拉的人,将有很大可能被判入狱长达20年,这包括资助(破坏特斯拉汽车)者,我们正在寻找你。”

关键字: 特朗普 AI 人工智能 特斯拉

1月22日消息,刚刚,新任美国总统特朗普放出重磅消息,将全力支持美国AI发展。

关键字: 特朗普 AI 人工智能

特朗普先生有两件事一定会载入史册,一个是筑墙,一个是挖坑。在美墨边境筑墙的口号确保边境安全,降低因非法移民引起的犯罪率过高问题;在中美科技产业之间挖坑的口号也是安全,美国企业不得使用对美国国家安全构成威胁的电信设备,总统...

关键字: 特朗普 孤立主义 科技产业

据路透社1月17日消息显示,知情人士透露,特朗普已通知英特尔、铠侠在内的几家华为供应商,将要撤销其对华为的出货的部分许可证,同时将拒绝其他数十个向华为供货的申请。据透露,共有4家公司的8份许可被撤销。另外,相关公司收到撤...

关键字: 华为 芯片 特朗普

曾在2018年时被美国总统特朗普称作“世界第八奇迹”的富士康集团在美国威斯康星州投资建设的LCD显示屏工厂项目,如今却因为富士康将项目大幅缩水并拒绝签订新的合同而陷入了僵局。这也导致富士康无法从当地政府那里获得约40亿美...

关键字: 特朗普 富士康

今年5月,因自己发布的推文被贴上“无确凿依据”标签而与推特发生激烈争执后,美国总统特朗普签署了一项行政令,下令要求重审《通信规范法》第230条。

关键字: 谷歌 facebook 特朗普

众所周知,寄往白宫的所有邮件在到达白宫之前都会在他地进行分类和筛选。9月19日,根据美国相关执法官员的通报,本周早些时候,执法人员截获了一个寄给特朗普总统的包裹,该包裹内包含蓖麻毒蛋白。

关键字: 美国 白宫 特朗普
关闭