函数参数传递方式,常常让人产生误解。先看一个简单的例子。
#include <stdio.h> void change(char *a);
void change_char(char *a);
int main(){
char a[]="abcdefg";
printf("before %s\n",a);
change(a);
printf("after %s\n",a);
change_char(a);
printf("after change char 'b',a is %s\n",a);
return 0;
}
void change(char *a)
{
a++; //改变了指针形参的大小哦
}
void change_char(char *a){ a++; //改变了指针形参的大小哦
*a='B'; }
例子中的change函数,对指针形参a进行了改变,按我以前的理解,这意味着指针将指向字符串“abcdefg”中的第二个字母‘b',printf输出应该是”bcdefg“。实际上,main函数中a的大小原封未动。运行结果如下:
before abcdefg after abcdefg
after change char 'b',a is aBcdefg事实胜于雄辩,我的理解显然有误。
在《c和指针》一书中提到,c函数的所有参数均以“传值调用“方式进行传递。参数(指针)实际上是一份拷贝,但在这份拷贝上执行间接访问操作所访问的是原先的数组。对指针形参执行间接访问操作,就是对指针所指向的内存位置上的内容进行修改。不管是”按值传递“还是”按地址传递“,其作用原理都是先拷贝,后操作。在上例中,a++表达式,将使得a的拷贝值加1,但是a的原始值不变。而*a操作,因为指针的特殊性,指向了另一个地址,操作指针参数的拷贝,即操作另一个地址上的内容,也就是将‘b'修改成’B‘。
上述解释有点绕,再来看看《c和指针》书上的两个例子,它们非常清楚的说明了一点:c函数的所有参数均以”传值调用“方式进行传递,也就是拷贝实参的方式
/*交换调用程序中的两个整数(没有效果)*/ void swap(int x,int y){ int temp; temp=x; x=y; y=temp; } /* 有效果,成功交换调用程序中的两个整数*/ void swap(int *x,int *y){ int temp; temp=*x; *x=*y; *y=temp; }