指针基础知识
C++中的指针是一大难点,开这篇文章整理一下乱掉的脑子。
本文主要参考《C++ Primer》
指针与引用的区别
指针与引用一样,都是对其他对象的间接访问,但区别就在于:
- 指针就是一个对象,可以先后指向不同的对象
- 引用并非对象,它只是所引用对象的一个别名,一旦定义给某个对象定义引用,则该引用不能更换给别的对象
符号的多重含义
对于指针的声明和使用过程中,有两个符号*
&
绕不过去,也经常是在这两个符号上,发出灵魂的质疑,这两个符号在声明和用在表达式里时意义截然不同。
int i = 42;
int &r = i; //&跟在类型名int后面,用于声明,表示 r 是一个引用
int *p; //*跟在类型名int后面,用于声明,表示 p 是一个指针
p = &i; //&在表达式中,表示取地址符
*p = i; //*在表达式中,表示解引用符,*p直接代表一个数
//对于 声明+初始化 一条龙,右侧的*是用于表达式中,表示解引用符(*p表示p指向的对象的内容)
//左侧的&出现在声明中,表示引用
int &r2 = *p;
空指针与野指针
int *p1 = nullptr;
int *p2 = 0;
int *p3 = NULL;
以上三种空指针的声明+初始化都是相同的。
一般在声明一个指针时,都要为其初始化,如果一时没有指向的对象,可以初始化为空指针。如果不初始化,就会变成野指针,野指针随机指向的内存中不一定存放着什么东西,操作野指针极其危险!下面就是野指针的形式:
int *p4; //野指针
指针赋值
可以分成两种情况
- 声明+初始化
- 修改指向
int val = 11;
int *p5 = &val; //声明+初始化
int *p6 = nullptr; //设为空指针或者指向其他合法对象
p6 = &val; //修改指向
为指针赋值,等号右边一定要是地址值,因为指针是一个对象,里面存放的是该指针所指向对象的地址值。
指针的复合类型
复合类型的声明
变量的定义包括:基本数据类型(base type)、声明符。同一条定义语句虽然base type相同,但是可以有不一样的声明符。
int i = 24, *p = &i, &r = i;
base type是int
,*
和&
都是声明符
指向指针的指针
使用*
的个数区分指针的级别, **
表示指向指针的指针。因为指针也是一个对象,所以也可以使用另一个指针指向该指针。
int val = 10;
int *p = &val;
int **pp = &p;
在表达式中解引用,对**的解引用分为两个级别
cout << *p << endl; //输出=val=10
cout << **pp << endl; //输出=val=10
cout << *pp << endl; //输出=指针p中存储的内容,即val的地址