数组名作为函数参数,传值调用(拷贝),实参与形参

数组名作为函数参数

概念说明

当一个数组名作为参数传递给一个函数时,数组名就是指向数组第一个元素的指针,此时传递给该函数的是该指针的一份拷贝。

函数如果对数组名进行了下标引用(即在函数中使用了该形参访问或修改数组),实际是对该指针执行了间接访问操作,通过这种间接访问,被调函数可以访问和修改主调函数中的数组元素。

这其实还牵扯到另外一个知识,如果想将一个数组传给另外一个数组,不能直接将数组名传过去,也不能对数组名使用++操作。见博客《数组-高级篇》和《指针与数组》,数组给数组赋值,数组初始化,见博客《数组-应用篇》。

“传值调用”

所有函数的参数都是通过传值方式进行的,但数组名参数使用却像是通过传址调用传递的,这只是现象表现,但实际上它仍然是传值调用。作为参数的数组名其实是个常量指针,下标引用实际执行的就是间接访问。

数组名的传值调用行为表现传递给函数的是参数的一份拷贝(指向数组起始位置的指针的拷贝),所以函数可以自由地操作它的指针形参,而不必担心会修改对应的作为实参的指针。你改变不了这个指针本身的值,因为它只是一个拷贝,如果想要修改它就要用到指针的指针。

  1. 1.传址调用是通过传递一个指向所需元素的指针,然后在函数中对该指针执行间接访问操作实现对数据的访问。

    2.所有的参数都是通过传值方式传递的。当然,如果你传递了一个指向某个变量的指针,而函数对该指针执行了间接访问操作,那么被调函数就可以修改那个变量。

    3.数组名作为参数时是类似的道理。这个参数(指针)实际上是通过传值方式传递的,函数得到的是该指针的一份拷贝,它可以被修改,但调用程序所传递的实参并不受影响。

    4.无论被调函数对参数(指针)如何进行修改,都不会修改调用程序的指针实参本身(但可能修改它所指向的内容)。

指针表示法形参与数组表示法形参

这里有一个有趣的问题。如果你想把一个数组名参数传递给函数,正确的函数形参应该是怎样的?它是应该声明为一个指针还是一个数组?

如上文所述,调用函数时实际传递的是一个指针,所以被调函数的形参实际上是个指针。但是,编译器也接受数组形式的函数形参。因此,下面两个函数原型是相等的:

int strlen( char  *string );
int strlen( char  string[]); 

这两个声明确实相等,但只是在当前相应的上下文环境中。如果它们出现在别处,就可能完全不同。

对于数组形参,你可以使用任何一种形式的声明。 你可以使用任何一种声明,但哪个“更加准确”?

答案是指针。因为实参实际上是个指针,而不是数组。

这就是为什么函数原型中的一维数组形参无需写明它的元素数目,

因为函数并不为数组参数分配内存空间。形参只是一个指针,它指向的是已经在其他地方分配好内存的空间。
这解释了为什么数组形参可以与任何长度的数组匹配——它实际传递的只是指向数组第1个元素的指针。
另一方面,这种实现方法使函数无法知道数组的长度。如果函数需要知道数组的长度,它必须作为一个显式的参数传递给函数。

**只有在函数原型或函数引用 ,才可以使用int data_p[] 代替 int data_p **

int data_p[] 代替 int* data_p都表示data_p是一个指向int型的指针,。但是int
data_p[]只能用于声明形式参数。 使用int
data_p[]可以让程序员知道,指针data_p指向的不仅仅是一个int类型的值,还是int类型的数组。

声明函数数组形参的形式

1.因为数组名是该数组首元素的地址,,作为主调函数要春递给被调函数的实参-数组名,要求形参是一个能够与其匹配的指针。此时,C编译器会把int data_p[] 和 int* data_p解释成一样的。

即data_p是指向int型的指针。,由于函数原型可以省略参数名,所以以下四种原型是等价的

int  fun_data_ctrl(int* data_p,int  num);
int  fun_data_ctrl(int*       ,int   );
int  fun_data_ctrl(int data_p[],int  num);
int  fun_data_ctrl(int       [],int  );
  1. 函数的定义中不能省略参数名
int  fun_data_ctrl(int*  data_p,int  num)
{
	//功能代码
}

与上面的定义形式等价

int  fun_data_ctrl(int  data_p[]_p,int  num);
{
	//功能代码
}
  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiawucha159

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值