C++指针和引用

主要说一下C++指针和引用在使用过程中需要注意的一些地方。
一、指针
1.指针其实就是内存地址,数据(无论是int/long/char等各种类型)存储在内存中,必然有找到存储数据的办法,这个办法就是找到存储这部分内存的地址就可以了。找到了地址就找到就找到了放到地址中的内容,这就是指针的功能。在C/C++中指针就是内存地址,取出地址中存放的内容的符号也是比较形象的,-> 是不是很像一个箭头!通过这个符号就可以取出当前地址下的内容。
当然了,还可以使用解引用,使用*来取出地址中的内容;

2.作为指针经常被作为参数传递,比如:

#include <stdio.h>

//求arg1+arg2=sum把结果保存到sum中
void testAdd(int* arg1, int*arg2, int*sum);

int main() {
	int arg1 = 12;
	int arg2 = 5;
	int sum = 0;
	printf("调用之前地址:arg1地址:%0xd  arg2地址:%0xd sum地址:%0xd\n", &arg1, &arg2, &sum);
	testAdd(&arg1, &arg2, &sum);
	printf("%d+%d=%d\n", arg1, arg2, sum);
	return 0;
}

void testAdd(int* arg1, int*arg2, int*sum) {
	*sum = *arg1 + *arg2;
	printf("调用之后地址:arg1地址:%0xd  arg2地址:%0xd sum地址:%0xd\n", arg1, arg2, sum);
}

输出结果:12+5=17
通过内存地址可以看到:
这里写图片描述
参数传递的确是传递的同一个地址中的内容。
以上计算是通过指针完成的。但是如果不适应指正呢?直接传值会怎样?我们重载一下函数:

void testAdd(int arg1, int arg2, int sum);
void testAdd(int arg1, int arg2, int sum) {
	sum = arg1 + arg2;
	printf("调用之后地址:arg1地址:%0xd  arg2地址:%0xd sum地址:%0xd\n", &arg1, &arg2, &sum);
}

运行一下,查看结果:
这里写图片描述
发现各个参数的地址都不一样了,而且计算的结果也不对。这是因为在调用函数testAdd时,系统会在函数内部自动的分配同类型的临时变量,并且把传递的参数复制给生成的临时变量。之后再函数中对这些变量的使用其实是对生成的临时变量的使用,与原来的变量不是同一个变量了。他们是位于内存中不同地址的不同变量。所以在函数中的变量和调用函数之外的变量虽然类型名字一样,但是不是同一块内存。因此结果也是不正确的。

二、引用
1.如果我们把上面的函数在修改一下,传递的参数改为引用。

void testAdd(int&arg1, int&arg2, int&sum);
void testAdd(int&arg1, int&arg2, int&sum) {
	sum = arg1 + arg2;
	printf("调用之后地址:arg1地址:%0xd  arg2地址:%0xd sum地址:%0xd\n", &arg1, &arg2, &sum);
}

然后运行一下,查看结果:
这里写图片描述`
返现运行也是正确的。
引用其实作用和指针的作用是一样的,指针是地址,引用是别名。举个例子:我给张三起了另外一个名字叫张三三,当我叫张三或者张三三时,他们都是同一个人。引用就是这样。
参数传递的是引用,在函数内部使用这个别名变量任然是函数外面定义的别名。在函数内部对这个变量的操作,也就是对在函数外部变量的操作。它们是内存中的同一块内存,只不过是不同的名称而已。

但是如果返回的是引用呢?网上很多人都说不要返回局部变量的引用,返回又如何?举个例子:

int& testAdd(int arg1, int arg2);
int& testAdd(int arg1, int arg2) {
	int sum = arg1 + arg2;
	printf("调用之后地址:arg1地址:%0xd  arg2地址:%0xd sum地址:%0xd\n", &arg1, &arg2, &sum);
	return sum;
}

编写完成之后,会在第一次编译的时候,出现如下警告:

warning C4172: 返回局部变量或临时变量的地址

忽略警告直接运行:
这里写图片描述
调用前和调用后的内存地址是不一样的,但是结果确实正确的。这是因为放返回的变量是临时变量的时候,临时变量会在函数调用完成后就释放掉内存了。返回时会重新分配一块同类型的内存一保存返回值。所以内存地址会不一样。

2.返回值是引用,对引用的操作
直接上代码,看下面的例子:

#include <stdio.h>

int gSum = 0;
int& testAdd(int arg1, int arg2);

int main() {
	int arg1 = 12;
	int arg2 = 5;
	printf("1.gSum地址:%0xd\n", &gSum);
	int sum = testAdd(arg1, arg2);
	sum++;
	printf("sum地址:%0xd\n", &sum);

	printf("2.gSum地址:%0xd\n", &gSum);

	printf("gSum=%d\n", gSum);
	return 0;
}

int& testAdd(int arg1, int arg2) {
	gSum = arg1 + arg2;
	return gSum;
}

gSum的值是17还是18?

看打印出来的结果:
这里写图片描述

gSum=17并且sum的地址和gSum的地址也是不一样的,为什么呢?这是因为testAdd函数虽然返回的是引用,但是接收返回值的并不是引用,认识具体的一个变量,相当于又重新分配了一块内存,然后给分配这块内存重新赋值。这块内存和gSum是不同的内存位置。
那么如果我想返回也是gSum呢,那么就要接收返回值的地方必须也是定义为引用。

int&sum = testAdd(arg1, arg2);//要定义成引用

重新运行一下:
这里写图片描述
sum和gSum的结果地址一样的,对sum的操作也就是对gSum的操作。sum就是gSum的别名引用。
以上!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值