引用型参数C语言交换值,C语言:值传递,地址传递和引用传递(example:值交换)(示例代码)...

于C语言中值传递、地址传递和引用传递的我个人理解。

通过一个例子:swap(交换两个整型变量的值)来表现!

1 #include

2 void swap1(int* a,int*b);3 void swap2(int& a,int&b);4 void swap3(int* a,int*b);5

6 voidmain(){7 printf("Hello World!\n");8 int a = 3;9 int b = 4;10 printf("bef swap, add of a = %d\n",&a);11 printf("aft swap, val of a = %d\n",a);12 //swap(a,b);

13 swap1(&a,&b);14 //swap2(a,b);15 //swap3(&a,&b);

16

17 printf("aft swap, add of a = %d\n",&a);18 printf("aft swap, val of a = %d\n",a);19 }20 //pass by value

21 void swap(int a,intb){22 int temp =a;23 a =b;24 b =temp;25 }26 //pass by address

27 void swap1(int* a,int *b){28 int temp = *a;29 *a = *b;30 *b =temp;31 }32 //pass by reference

33 void swap2(int& a,int&b){34 int temp =a;35 a =b;36 b =temp;37 }38 //pass by value ?

39 void swap3(int* a,int *b){40 int* temp =a;41 a =b;42 b =temp;43 }

上面的函数,四个swap函数,输出结果:

swap(a,b):

c838777cd6ea68109e6d2f528e42b8f5.png

swap1(a,b):

cf30c5d729275b9f499ca15b8407f44d.png

swap2(a,b):

d2625e9d27e9e0d65b1ebdc6bb25ab11.png

swap3(a,b):

ea3520feea4c55ebf449530d0ba48ab9.png

我们看到,真正起作用的是swap1和swap2.这两个分别是地址传递和引用传递。swap是典型的值传递,swap3是什么我后面会讲。

分析!

0,值传递

这个比较简单,实参a 原本指向地址 1638212,代表1638212这个地址的值是3。在swap函数中,实参a将值拷贝给形参a,形参a此时也在内存中拥有地址,地址= xxxx,值为3,在所有的函数体内的操作,都是对 xxxx这个地址的操作,所以并不会影响实际参数的值。

1,地址传递

这个对于理不清指针是什么的同学来说比较难。在这里我们习惯把指针写成int* a,int* b而不是int *a,int *b。我们可以这样理解:指针是一种特殊的数据类型,若 int c = 5;int* a = &c;则a是一个指针变量,它的值是c的地址!星号“*”是一个取值操作,和号“&”是一个取址操作。所以此时单纯看a和b都是一个整数,它们表示地址,进行取值操作之后就可以得到相应地址的值。函数接受两个类型为指针的变量,实际接受的是a和b,即两个地址。所以现在分析函数体:

1 int temp = *a;//取出地址a的值,并赋值给整型变量temp

2 *a = *b; //取出地址b的值,并将这个值赋给地址a指向的值

3 *b = temp; //将temp的值赋给地址b所指向的值

因此,我们看到,由于函数传入的是地址,而函数体内又对地址进行取值和赋值操作,所以相对应的地址的值发生了改变。但是地址并没有实际改变,从函数的输出来看,a的地址并不会改变。在C语言中,函数在运行的时候会对每个变量分配内存地址,分配之后只要变量不被销毁,这个地址不能改变。&a = &b;是无法编译通过的。

2,引用传递

这个理解起来更简单,我们这样理解引用,引用是变量的一个别名,调用这个别名和调用这个变量是完全一样的。所以swap2的结果可以解释。值得注意的是,由于引用时别名,所以引用并不是一种数据类型,内存并不会给它单独分配内存,而是直接调用它所引用的变量。这个与地址传递也就是指针是不一样的(也就是说一个指针虽然指向一个变量,但是这个指针变量在内存中是有地址分配的),下面代码进行验证。

1 voidmain(){2 printf("Hello World!\n");3 int a = 3;4 int b = 4;5 int* c = &a;//c是指向a的指针

6 int& d = b;//d是b的引用,alias of b = d

7 printf("val of a = %d\n",a);8 printf("add of a = %d\n",&a);9 printf("val of c = %d\n",c);10 printf("add of c = %d\n",&c);11 printf("val of b = %d\n",b);12 printf("add of b = %d\n",&b);13 printf("val of d = %d\n",d);14 printf("add of d = %d\n",&d);15 }

输出结果:

f37c01351d266072e94ae6e2046f59f0.png

我们看到c的值是a的地址,c的地址是单独分配的;而d的值是b的值,d的地址是b的地址!

4,关于swap3怎么解释。

我认为swap3是一种值传递,如果我们把int*完全当做跟int一个级别的数据类型,那么swap3和swap两个函数是一摸一样的。只不过后者传入的是变量a,b的拷贝值,而后者传入的是变量a,b的地址的拷贝值;前者不能反应在外部,后者也不能。

最后,我们注意,对于应用,如果我们有代码:int a = 3; int& b = a;(b is an alias of a)b = 10;那么我们会发现a的值此时也变成了10。

但是在java中,如果我们把java的引用简单想象成这里的引用,是有问题的。因为如果一个函数出入一个对象Person person = new Person("ZHANG San"),而在函数体内进行这个操作:person = new Person("LI Si");那么person的值并不能被改变,所以我们说java的函数传递都是值传递。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值