C语言所有函数的参数都是以"传值调用"的方式进行传递,这意味着函数将获得参数值的一份拷贝。这样函数可以放心地修改这个拷贝值,而不用担心修改调用程序实际传给它的参数。
C语言规则很简单:所有参数都是"传值调用"
但是,如果被传递的参数是一个数组名,并且在函数中使用下标引用该数组的参数,那么在函数中对数组元素进行修改实际上修改的是调用程序中的数组元素。函数将访问调用程序的数组元素,数组不会被赋值。
数组参数的这种行为似乎与传值调用规则相悖,但是此处并无矛盾---数组名(的值)实际上是一个指针,传递给函数的就是这个指针的一份拷贝,下标引用实际上是间接访问的另一种形式,它可以对指针执行间接访问操作,访问指针指向的内存位置。
当一个数组名作为参数传递给一个函数时会发生什么情况呢?你现在已经知道数组名的值就是一个指向数组第一个元素的指针,所以很容易明白此时传递给函数的是一份该指针的拷贝。函数如果执行下标引用,实际上是对这个指针执行间接访问操作,并且通过这种间接访问,函数可以访问和修改调用该程序的数组元素。
那么数组的传值调用行为有时表现在什么地方呢?传递给函数的是参数的一份拷贝(指向数组起始位置的指针的拷贝),所以函数可以自由地操作它的指针参数,而不必担心会修改对应的实参指针。
所以,此处并不存在矛盾:所有的参数都是通过传值方式传递的。当然,如果你传递了一个指向某个变量的指针,而函数对该指针执行了间接访问操作,那么函数就可以修改那个变量,尽管初看上去并不明显,但数组名作为参数时所发生的正是这种情况。这个参数(指针)实际上是通过传值方式调用,函数得到的是该指针的一份拷贝。
如果你想把一个数组名作为参数传递给函数,正确的函数形参是怎样的?它是应该声明为一个指针还是一个数组?
正如你所看到的那样,调用函数时实际传递的是一个指针拷贝,所以,函数的形参实际上是一个指针,但为了程序员新手更容易上手,编译器也接受数组形式的函数形参。因此,下面两个函数原型是相等的:
int strlen(char *string);
int strlen(char string[]);
你可以使用任何一种声明,但哪个"更加准确"呢?答案是指针。因为实参实际上是个指针,而不是数组。同样,在这里表达式sizeof string的值是指向字符的指针的长度,而不是数组的长度。
链接原文:[url]https://mp.weixin.qq.com/s/DCeQdUnUcGTGbq6Otjp7P 如有侵权,请联系删除。
|