C++编程基础|多级指针
- 一级指针
- 二级指针
- 三级指针
- 多级指针的意义
- 一维数组与数组指针
- 二维数组与数组指针
在看代码时发现下面的内容
GridNodePtr *** GridNodeMap;
struct GridNode;
typedef GridNode* GridNodePtr;
显而GridNodePtr
是结构体GridNode
首地址指针
那么GridNodeMap
是什么?它实际上是一个四级指针
这种用法不多,这里的含义之后再给出
下面分别梳理下:
- 一级指针
- 二级指针
- 三级指针
一级指针
一级指针其实就是我们平时常见的普通指针
int a = 15;
int * b = &a; //一级指针,定义一个指针变量b,将整型变量a的地址(指针)赋值给b
一级指针,定义一个指针变量b,将整型变量a的地址(指针)赋值给b
指针其实是一个内存地址,对于一个内存单元来说,单元的地址即为指针。
平时常用的指针则是指针变量
指针变量从字面意思上可以看出是存储指针的一种变量类型。在C语言中,允许用一个变量来存放指针,这种变量称为指针变量。
也就是,指针是一个地址,是一个常量。而指针变量却可以赋予不同的指针(指针也就是地址),是变量。但我们常把指针变量简称为指针。
指针其实就是地址的别称,而指针变量就是存放这个地址的,所以我们平时说的定义一个指针,就是定义一个指针变量,我们可以给这个指针变量赋上变量的地址、数组首地址、结构体首地址等等
另外注意一下指针变量的赋值只能赋予地址
&:取地址运算符,一般形式为: &变量名
*:指针运算符(也就是获取该指针所指向的数据),一般形式为: *指针变量
二级指针
二级指针则是指向一级指针的指针,也就是说如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。
int a = 15;
int * b = &a; //一级指针
int **c = &b; //二级指针,指针c指向的是指针b,也就是说二级指针c存储的是一级指针b的地址
二级指针,指针c指向的是指针b,也就是说二级指针c存储的是一级指针b的地址
指针变量也是一种变量,也会占用存储空间,也可以使用&获取它的地址,所以二级指针才可以指向一级指针的地址。
三级指针
三级指针则是指向二级指针的指针。所以规律就是n 级指针就是 指向 n-1 级指针的 指针
int a = 15;
int * b = &a; //一级指针
int **c = &b; //二级指针,指针c指向的是指针b,也就是说二级指针c存储的是一级指针b的地址。
int ***d = &c; //三级指针,指针d指向的是指针c的地址
三级指针前面加一个取地址运算符,也就是&d,则取出的是其自身的存储地址。
而”*d”则是取到指针c的地址,而”**d”则是取到指针b的地址,而”***d”则是取到a地址上的数据。
想要获取指针指向的数据时,一级指针加一个*,二级指针加两个*,三级指针加三个*
int **a = new int *[2]; //一维 for (int i=0; i<2; i++) { (*a+i) = new int[i+1]; //二维变长 }
多级指针的意义
这样的指来指去目的是啥呢?有什么意义呢?
其中有些是如果遇到需要修改指针的值,使它指向另外一个节点,或变量,与其使用大量代码直接修改它的值,不如使用它的二级指针,直接修改其地址值,会大大减少代码冗余,提高代码质量。
但是最开始的例子是为了用多级指针去表示多维数组
一维数组与数组指针
假如有一维数组如下:
char a[3];
该数组一共有3个元素,元素的类型为char
一个数组的数组名代表其首元素的首地址也就是相当于&a[0]
,而a[0]
的类型为char
&a[0]
类型为char *
可以定义如下的指针变量,指向该数组
char* p = a;//相当于char * p = &a[0]
a和&a[0]代表的都是数组首元素的首地址
&a的值打印出来,会发现该值也等于数组首元素的首地址
&a虽然在数值上也等于数组首元素首地址的值,但是其类型并不是数组首元素首地址类型
对数组名进行取地址操作,其类型为整个数组
很多人对类似于a+1,&a+1,&a[0]+1,sizeof(a),sizeof(&a)等感到迷惑,其实只要搞清楚指针的类型就可以迎刃而解。比如在面对a+1和&a+1的区别时,由于a表示数组首元素首地址,其类型为char*,因此a+1相当于数组首地址值+sizeof(char);而&a的类型为char (*)[3],代表整个数组,因此&a+1相当于数组首地址值+sizeof(a)。(sizeof(a)代表整个数组大小,前文第7条说明,但是无论数组大小如何,sizeof(&a)永远等于一个指针变量占用空间的大小,具体与系统平台有关)
二维数组与数组指针
假如有如下二维数组:
char a[3][2];
实际上并不存在多维数组,
可以将a[3][2]看成是一个具有3个元素的一维数组,只是这三个元素分别又是一个一维数组
实际上,在内存中,该数组的确是按照一维数组的形式存储的,存储顺序为(低地址在前):a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]
如上图所示,我们可以将数组分成两个维度来看,首先是第一维,将a[3][2]看成一个具有三个元素的一维数组,元素分别为:a[0]、a[1]、a[2],其中,a[0]、a[1]、a[2]又分别是一个具有两个元素的一维数组(元素类型为char)。从第二个维度看,此处可以将a[0]、a[1]、a[2]看成自己代表”第二维”数组的数组名,以a[0]为例,a0代表的一维数组是一个具有两个char类型元素的数组,而a[0]是这个数组的数组名(代表数组首元素首地址),因此a[0]类型为char * ,同理a[1]和a[2]类型都是char * 。而a是第一维数组的数组名,代表首元素首地址,而首元素是一个具有两个char类型元素的一维数组,因此a就是一个指向具有两个char类型元素数组的数组指针,也就是char(*)[2]。