目录
想实现一个指针做函数返回值的操作,但发现怎么也实现不了,如下面的代码,想像函数中传入一个变量x,然后,返回这个变量的指针,然后,通过这个返回的指针,再将这个变量中存放的值,打印出来。
问题代码:
#include <iostream>
using namespace std;
int* getA3(int a)
{
return &a;
}
void main()
{
int x = 10;
int *a3 = getA3(x);
//int* a3 = getA3(x);
printf("a3:%d\n", *a3);
system("pause");
return;
}
经过分析后,找出这段代码的问题有很多。
区分"&"符号做引用和做取地址场景的区别
和类型在一起的是引用,和变量在一起的是取址
1)引用在赋值=的左边,而取地址在赋值的右边
,比如:
int a=3;
int &b=a; //引用
int *p=&a; //取地址
2)和类型在一起的是引用,和变量在一起的是取址。
举例同样如上,还有下例:
int function(int &i)
{
} //引用
那么问题来了,下面这个场景"&"是做什么作用的呢?
return &a;
这个场景下,是返回一个内存地址值,也就是变量a的地址,通常用于指针返值。“&”充当的是取地址符。
如何实现取地址操作
int *getA3(int a)
{
int *p = &a;
return p;
}
取地址操作的时候,通过"&"来取,通过"int *p"来接收,其中,p是指针变量。但还是存在问题的。
被调函数中的内存管理
以上面那段有问题的代码为例,我把一个变量值,传递到被调函数中去的时候,内存中会创建一个变量a,然后将传入的值给a,那么最后被调函数返回的是a的地址,当被调函数运行结束,会进行析构了,那么对于的a的内容也被擦除了,而再通过对应的返回的a的地址去返回的时候,访问的就是乱码了!
比如,下面的这样更改的方式:
#include <iostream>
using namespace std;
int *getA3(int a)
{
int *p = &a;
printf("被调函数中,x的地址:%d\n", &a);
printf("被调函数中,x的地址的指针变量:%d\n", p);
return p;
}
void main()
{
int x = 10;
int *w = &x;
printf("原始的x的地址:%d\n", &x);
printf("原始的x的地址的指针变量:%d\n", w);
int *a3 = getA3(x);
printf("取出的指针变量:%d\n",a3);
printf("a3:%d\n", *a3);
int *a4 = &x;
printf("a4:%d\n", *a4);
system("pause");
return;
}
同样的方式,来添加一个a4变量,只不过是没有将其放被调函数里面,直接在主调函数中进行,就会发现是没问题的。
通过传递引用做函数参数
#include <iostream>
using namespace std;
int *getA3(int &a)
{
int *p = &a;
printf("被调函数中,x的地址:%d\n", &a);
printf("被调函数中,x的地址的指针变量:%d\n", p);
return p;
}
void main()
{
int x = 10;
int *w = &x;
printf("原始的x的地址:%d\n", &x);
printf("原始的x的地址的指针变量:%d\n", w);
int *a3 = getA3(x);
printf("取出的指针变量:%d\n",a3);
printf("a3:%d\n", *a3);
int *a4 = &x;
printf("a4:%d\n", *a4);
system("pause");
return;
}
如果传进被调函数中的是一个引用,就不会出现上面的问题了,因为引用只是一块儿内存空间的别名,别名可以被析构,但对于的内存空间因为有其他别名还与之对应,所以,不会析构掉。运行如下:
"*p"不等同于"&a"
如下这段程序:
#include <iostream>
using namespace std;
void main()
{
int x = 10;
int *w = &x;
printf("int *w = &x;\n");
printf("&x:%d\n", &x);
printf("*w:%d\n", *w);
printf("w:%d\n", w);
system("pause");
return;
}
我就发现了一个问题,对于"int *w = &x;" ,这条语句,是不是就意味着"*w"等同于"&x"呢?经过实际编译的打脸,让我觉得一切并没有那么简单:
编译结果表明:"&x"是对应变量所存放的内存地址;而"*w"直接对应的是指针变量指向的内存空间中的实际数值,这俩其实并不相对,但却是通过等号来相连接的。
这个现象值得注意和思考,我对这条语句的理解是,首先,创建了int类型的指针变量w,然后,取变量x的地址,最后,将这个内存地址赋值给了指针变量w,在这个过程中,"int *w"应该拆分成"int *"(代表整型的指针变量类型)和"w"(指针变量)来理解,而不能当做"int"和"*w"来理解。最后,“*w”的对应的是将w变量中存放的内存地址中的值。