传值和传址

【更新】    2012-7-11,添加特例分析

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初始化。对这种做法有高见的请留言!

【效率比较】

一般而言,传址比传值效率高。因为传值对整个类型进行了拷贝,而传址只复制了地址。比如,现有一个结构体,存储了大量的数据。传值拷贝了整个结构体,而传址只是拷贝了地址。

 

【特例分析-2012.7.11】

C语言的函数参数传递都是传值调用,如何理解数组的“传址调用”呢?

数组名实质上是一个指针常量(字符串与指针常量),所谓指针常量,就是“指针是常量”,即不能改变指针的地址(是const的),但能改变指针指向的内容。传递给函数的参数为数组时,传递给函数的是参数的一份拷贝(指向数组起始位置的指针的拷贝),所以函数可以自由的操作它的指针形参,而不必担心会修改对应的作为实参的指针。从指针常量的角度看,对应作为实参的指针实质上也是不可被修改的。

“传址”又怎么理解呢?因为函数传递的是指向某个变量的指针,而函数对该指针执行了间接访问操作,所以函数可以通过“数组传址”的方式修改变量的值。但指针本身是常量,是一份拷贝,所以不会被修改。

 

【2012-09-14】

本质上都是传值调用,传递的都是参数的一份拷贝,目的是为了使函数可以放心的修改这个拷贝值。所谓的“传址”,是指传递的是指针的一份拷贝,只不过在函数内部,通过间接访问,可以访问和修改原地址存储的值。

 

转载请标明出处,仅供学习交流,勿用于商业目的

Copyright @ http://blog.csdn.net/tandesir

 

 

 

 

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值