C语言中所有的参数都是传值调用,意味着函数将获得参数值的一份拷贝。函数可以放心的修改这份拷贝,而不必担心会修改实际传递给他们的形参。但这种方式,有时候也会带来麻烦。如下例交换函数:
void swap(int a, int b) { int temp; temp = a; a = b; b = temp; }函数调用如下:
int main(void) { int x = 5, y = 10; swap(x,y); printf("x = %d, y = %d", x, y); return 0; }执行这个函数后,x,y并没有像预期的进行交换。原因如下:
执行swap(x,y)时,swap(int a, int b)形参a,b获得了x,y的拷贝。在swap函数中,a,b确实交换了。但a,b获取的是x,y的拷贝,x,y实质上并没有改变。函数调用完成后,a,b同时也结束生存周期。
有没有办法改变调用函数中的变量呢?这就有了传址调用的概念。传址调用实质上也是一种传值调用。只不过这个值很特殊,是地址值。
现将swap改写如下:
void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; }函数调用如下:
int main(void) { int x = 5, y = 10; swap(&x, &y); printf("x = %d, y = %d", x, y); return 0; }这时,就实现了交换的功能。原因如下:
执行swap(x,y)时,swap(int a, int b)形参*a,*b获得了x,y地址的拷贝。在swap函数中,*a和*b进行交换。虽然也是交换拷贝的内容,但此时改变的是地址,而这个地址就是x,y的地址,也就实现了x,y的互换。形参只是一个指针,它指向的是已经在其他地方分配好内存的空间。
还有一种做法,测试通过了:
void swap(int &a, int &b) { int temp; temp = a; a = b; b = temp; }函数调用如下:
int main(void) { int x = 5, y = 10; swap(x, y); printf("x = %d, y = %d", x, y); return 0; }函数调用时,进行了强制转换,将x转换为&x,然后将&a初始为&x的拷贝,&b初始化为&y的拷贝。所以实质上也是交换的地址。但不认同这种写法,因为引用是必须初始化的。而函数原型中,没有显式的对&a,&b初始化。对这种做法有高见的请留言!
【效率比较】
一般而言,传址比传值效率高。因为传值对整个类型进行了拷贝,而传址只复制了地址。比如,现有一个结构体,存储了大量的数据。传值拷贝了整个结构体,而传址只是拷贝了地址。