关于指针、引用、值传递的学习

本文详细解析了C++中值传递、引用传递、指针传递及指针的引用传递的区别与应用场景,并通过示例代码展示了不同情况下的内存变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天上午写代码的时候,遇到了指针、引用的问题,搞了一上午,终于搞明白了,但是发现有一个大哥的文章已经深刻而且清晰的总结了这个问题。转载文章,也算是给自己留个总结。文章原链接如下:http://blog.youkuaiyun.com/whzhaochao/article/details/12891329?userName=keke193991&userInfo=Mli6k1JWU1bgQxtPPQseFppd2temu%2FVmmAgpvuMGxLE%2Bp79qBMQ3%2BN8Trn2ktHDv2S8Ke1U6vChEtG7McbIzuAO4pM6WLGhpqFK8CTVablTCmVlq%2Bvf3CMGoRxQNkq1g

全文转载如下:

1.值传递

  1. void f( int  p){  
  2.     printf("\n%x",&p);  
  3.     printf("\n%x",p);  
  4.     p=0xff;  
  5. }  
  6. void main()  
  7. {  
  8.     int a=0x10;  
  9.     printf("\n%x",&a);  
  10.     printf("\n%x\n",a);  
  11.     f(a);  
  12.     printf("\n%x\n",a);  
  13. }  
void f( int  p){
	printf("\n%x",&p);
	printf("\n%x",p);
	p=0xff;
}
void main()
{
	int a=0x10;
	printf("\n%x",&a);
	printf("\n%x\n",a);
	f(a);
	printf("\n%x\n",a);
}


通过上例我们可以看到,int a=0x10,存放的地址为0x12ff44,值为10,当调用f(a)时,传递给p的值为10,但是p的地址为0x12fef4,当改变p=0xff,时是改变地址为0x12fef4中的内容,并没有改变0x12ff44中的内容,所以调用f(a),后a的值仍然为0x10,所以值传递无法改变变量的值。示意图如下:


2.引用传递

  1. void f( int & p){  
  2.     printf("\n%x",&p);  
  3.     printf("\n%x",p);  
  4.     p=0xff;  
  5. }  
  6. void main()  
  7. {  
  8.     int a=0x10;  
  9.     printf("\n%x",&a);  
  10.     printf("\n%x\n",a);  
  11.     f(a);  
  12.     printf("\n%x\n",a);  
  13. }  
void f( int & p){
	printf("\n%x",&p);
	printf("\n%x",p);
	p=0xff;
}
void main()
{
	int a=0x10;
	printf("\n%x",&a);
	printf("\n%x\n",a);
	f(a);
	printf("\n%x\n",a);
}

通过上面引用传递传递案例我们可以看到,调用f(a)时,传递给p的是a的地址,所以p和a的地址都是0X12ff44,所以p就是a,改变p当然能改变a。示意图如下:

3.指针传递

  1. void f( int*p){  
  2.     printf("\n%x",&p);  
  3.     printf("\n%x",p);  
  4.     printf("\n%x\n",*p);  
  5.     *p=0xff;  
  6. }  
  7. void main()  
  8. {  
  9.     int a=0x10;  
  10.     printf("\n%x",&a);  
  11.     printf("\n%x\n",a);  
  12.     f(&a);  
  13.     printf("\n%x\n",a);  
  14. }  
void f( int*p){
	printf("\n%x",&p);
	printf("\n%x",p);
	printf("\n%x\n",*p);
	*p=0xff;
}
void main()
{
	int a=0x10;
	printf("\n%x",&a);
	printf("\n%x\n",a);
	f(&a);
	printf("\n%x\n",a);
}



通过指针传递的案例我们可以看到,调用f(&a)是将a的地址0x12ff44传递给p,则*p就指向了a的内容,改变*p后,a的内容自然就改变了,示意图如下:


4.指针的引用传递

  1. void f( int*&p){  
  2.     printf("\n%x",&p);  
  3.     printf("\n%x",p);  
  4.     printf("\n%x\n",*p);  
  5.     *p=0xff;  
  6. }  
  7. void main()  
  8. {  
  9.     int a=0x10;  
  10.     printf("\n%x",&a);  
  11.     printf("\n%x\n",a);  
  12.     int *b=&a;  
  13.     printf("\n%x",&b);  
  14.     printf("\n%x",b);  
  15.     printf("\n%x\n",*b);  
  16.     f(b);  
  17.     printf("\n%x\n",a);  
  18. }  
void f( int*&p){
	printf("\n%x",&p);
	printf("\n%x",p);
	printf("\n%x\n",*p);
	*p=0xff;
}
void main()
{
	int a=0x10;
	printf("\n%x",&a);
	printf("\n%x\n",a);
	int *b=&a;
	printf("\n%x",&b);
	printf("\n%x",b);
	printf("\n%x\n",*b);
	f(b);
	printf("\n%x\n",a);
}



为了使用指针的引用传递我们要新建一个指针b,然后将b的引用传递给p,其实p就是b的一个拷贝,*p=*b都指向a,所以改变*p的内容也就改变a的内容。示意图如下:

我们再来看一下如果不用指针的引用传递会出现什么结果
  1. void f( int*p){  
  2.     printf("\n%x",&p);  
  3.     printf("\n%x",p);  
  4.     printf("\n%x\n",*p);  
  5.     *p=0xff;  
  6. }  
  7. void main()  
  8. {  
  9.     int a=0x10;  
  10.     printf("\n%x",&a);  
  11.     printf("\n%x\n",a);  
  12.     int *b=&a;  
  13.     printf("\n%x",&b);  
  14.     printf("\n%x",b);  
  15.     printf("\n%x\n",*b);  
  16.     f(b);  
  17.     printf("\n%x\n",a);  
  18.     printf("\n%x\n",b);  
  19. }  
void f( int*p){
	printf("\n%x",&p);
	printf("\n%x",p);
	printf("\n%x\n",*p);
	*p=0xff;
}
void main()
{
	int a=0x10;
	printf("\n%x",&a);
	printf("\n%x\n",a);
	int *b=&a;
	printf("\n%x",&b);
	printf("\n%x",b);
	printf("\n%x\n",*b);
	f(b);
	printf("\n%x\n",a);
	printf("\n%x\n",b);
}


从结果中我们可以看到调用f(b)时,传递给p的是b的内容,但是&b,和&p是不一样的,虽然*p和*b都指向a。示意图如下:


5.错误案例


  1. #include <stdio.h>   
  2. #include <malloc.h>   
  3. #include <string.h>   
  4.   
  5. void Allocate(char* p,int size){  
  6.   
  7.     printf("\n%x",&p);  
  8.     printf("\n%x",p);  
  9.   
  10.     p=(char*)malloc(size);  
  11. }  
  12. void Free(char* p){  
  13.     free(p);  
  14. }  
  15. void main()  
  16. {  
  17.     char *str=NULL;  
  18.     printf("\n%X",&str);  
  19.     printf("\n%X",str);  
  20.     Allocate(str,100);  
  21.     strcpy(str,"Hello World!");  
  22.     printf("\n%s",str);  
  23.     Free(str);  
  24.     printf("\nstr=%s",str);  
  25.       
  26. }  
#include <stdio.h>
#include <malloc.h>
#include <string.h>

void Allocate(char* p,int size){

	printf("\n%x",&p);
	printf("\n%x",p);

	p=(char*)malloc(size);
}
void Free(char* p){
	free(p);
}
void main()
{
	char *str=NULL;
	printf("\n%X",&str);
	printf("\n%X",str);
	Allocate(str,100);
	strcpy(str,"Hello World!");
	printf("\n%s",str);
	Free(str);
	printf("\nstr=%s",str);
	
}



当执行strcpy(str,"Hello World!"),时会报Unhandled exception in CPoint.exe:0xC0000005:Access Violation,这是因为我们参用的是指针传递,从运行结果我们可以看到str的地址为0x12ff44,当调用Allocate(str,100)时,传递给p的是str,的内容也就是0,所以p为0,但是&p并不是和&str一样的,所以在运行p=(char*)malloc(size)时,是给0x12fef0分配的100个字节,并没有给0x12ff44分配字节,所以*str还是空。所以会报错。

5.正确案例

  1. #include <stdio.h>   
  2. #include <malloc.h>   
  3. #include <string.h>   
  4.   
  5. void Allocate(char*& p,int size){  
  6.     printf("\n%x",&p);  
  7.     printf("\n%x",p);  
  8.     p=(char*)malloc(size);  
  9. }  
  10. void Free(char* p){  
  11.     free(p);  
  12. }  
  13. void main()  
  14. {  
  15.     char *str=NULL;  
  16.     printf("\n%X",&str);  
  17.     printf("\n%X",str);  
  18.     Allocate(str,100);  
  19.     strcpy(str,"Hello World!");  
  20.     printf("\n%s",str);  
  21.     Free(str);    
  22. }  
#include <stdio.h>
#include <malloc.h>
#include <string.h>

void Allocate(char*& p,int size){
	printf("\n%x",&p);
	printf("\n%x",p);
	p=(char*)malloc(size);
}
void Free(char* p){
	free(p);
}
void main()
{
	char *str=NULL;
	printf("\n%X",&str);
	printf("\n%X",str);
	Allocate(str,100);
	strcpy(str,"Hello World!");
	printf("\n%s",str);
	Free(str);	
}



因为指针引用传递的是指针的拷贝,所以&str和&p,是地址是一样的,所以对p分配内容空间也就是对str分配空间,所以没有问题!


但是需要说明的一点,指针也好、引用也罢,在C/C++中本质上都是值传递,但是,可以通过不同的控制方式,比如指针、比如引用从而达到一定的效果。或者说这就是计算机吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值