浅谈指针与引用
一. 指针
1.什么是指针:
指针是一种特殊的数据类型,使用它可以定义指针变量,指针变量中存储的是整型数据,代表了内存的编号,通过这个编号访问到对应的内存。
2.为什么使用指针:
a、函数与函数之间是相互独立的,但是有些时候需要共享变量
传参是单向值传递
全局变量容易命名冲突
使用数组还需要传递长度
函数的命名空间是相互独立的,但是地址空间是同一个,所以指针可以解决这个问题
b、由于函数传参是值传递(内存拷贝),对于字节数较多的变量,值传递的效率较低,如果传递的是变量的地址,只需要传递4|8字节。
c、堆内存无法取名,它不像stack、bss、data让变量名与内存建立关系,只能使用指针来记录堆内存的地址编号从而使用该堆内存。
二引用
1.什么是引用:引用就是取别名(外号)
引用就是用一个新的标识符与另一个标识符的内存建立绑定关系,从而使一块内存对应多个标识符。
2.引用的基本特点:
a、引用必须初始化,也就是必须有引用目标。
不存在空的引用,但有可能存在悬空引用(变量已经销毁,但名还留着)。
b、可以引用无名对象或临时对象,但必须使用常引用。
c、引用不能更换目标
引用一旦定义、初始化完成后就和普通变量一样,它就代表了引用目标,一旦引用终身不能更换引用目标(没有这种语法)
d、如果引用的目标具备const属性,那么引用也必须带const
3、什么时候使用引用
参数型引用 int func(int &a)
1、使用引用作为函数参数,能达到指针的效果(函数之间共享局部变量),但不具备指针的危险性
2、函数的实现有较大的主动权,是否使用引用由函数的实现者决定。
3、引用当做函数的参数,传参的效率更高,比指针还高,指针至少需要4字节内存空间来存储变量的地址,而引用只是增加了一条标识符与内存的绑定记录。
返回值型引用 int& func(void)
1、使用引用当做函数的返回值,传参的效率高,但接受者也要使用引用才能提高效率,否则还是内存拷贝
2、不要返回局部变量的引用,否则会造成悬空引用。
三引用与指针的区别:
相同点:都可以跨函数共享变量(获取返回值),都可以提高函数的传参效率
不同点:
引用 指针
取名机制 数据类型
不需要额外的存储空间 需要4/8字节存储
映射关系 指向关系
悬空引用 野指针、空指针、越界、脏数据
不能为空 可以为空
无法与堆配合 可以配合使用堆内存
直接访问目标 需要解引用
没有多级引用 但可以有多级指针
可以定义数组指针(int (*arrp)[10] ) 也可以定义数组引用(int (&array)[10])
可以定义函数指针 也可以定义函数引用
引用的优点:安全、效率高 缺点:没有管理内存的能力
指针的缺点:危险,需要额外的内存 优点:无所不能
四实列
1.执行以下程序输出的结果是:
#include<stdio.h>
char *c[] = { “我是大师兄”, “二师弟”, “大师兄很帅”, “二师弟真帅" };
Char **cp[] = { c+3, c+2, c+1, c };
Char ***cpp = cp;
int main(void)
{
printf("%s\n", **++cpp); //1
printf("%s\n", *--*++cpp+3); //2
printf("%s\n", *cpp[-2]+3); //3
printf("%s\n", cpp[-1][-1]+1); //4
return 0;
}
1 输出大师兄很帅 2 输出结果为师兄 3 输出结果为真帅 4 输出结果为师弟
2.引用常数与悬空引用:
#include <iostream>
using namespace std;
const int& func(void)//加const因为return b的返回值是一个常数
{
const int& b = 10;//加const因为b是一个常数
return b;
}
int main(int argc,const char* argv[])
{
int a = 3 , b = 7;
const int& num = a+b;//加const因为a+b的结果是一个常数
const int& num1 = func();//加const因为func()的返回值是一个常数
cout << num1 << endl;
cout << num << endl;
cout << num1 << endl;//局部变量已被销毁,悬空引用
}