(超级棒)C++基础·笔记——多级指针的使用【指针的总结②】
~QQ:3020889729
~小蔡
一级指针的复习
声明方式
方式: 数据类型* 变量名 = 地址 ; (Example:int* p = &a;)
#include "iostream"
using namespace std;
int main()
{
int a = 0;//初始化为0
int* p = &a;//指针声明,务必初始化地址
//也可以这样:int* p = NULL; p = &a;
*p = 8;//修改地址上的数据
cout << "a = " << a << endl;//输出此时a的值
cout << "*p = " << *p << endl;//输出指针p的值
return 0;
}
一级指针的理解
一级指针可以理解是某一个地址的操作符——可以对该地址上的内容(数据)进行修改。
二级指针的理解
声明方式
方式:数据类型** 变量名 = 指针的地址/地址的地址;(Example:int* q = &a; int** p = &q; )
#include "iostream"
using namespace std;
int main()
{
int a = 0;
int* adress = &a;//一级指针获取a的地址
int** adress_value =&adress;//二级指针获取一级指针adress的地址
cout << "The adress of menber:" << endl;
cout << "a = " << hex << &a << endl; //输出a的地址
cout << "First pointer adress = " << hex << adress << endl;//输出一级指针的值
cout << "Second pointer adress = " << hex << adress_value << endl;//输出二级指针的值
cout << "\n\n";
cout << "The value of menber:" << endl;
cout << "a = " << a << endl;//输出a的值
cout << "First pointer value = " << *adress << endl;//输出一级指针指向的值
cout << "Second pointer value(first) = " << *adress_value << endl;//输出二级指针一级指向的值
cout << "Second pointer value(second) = " << **adress_value << endl;//输出二级指针二级指向的值
return 0;
}
结果显示:(adress输出中,可以看出一级指针的值和变量的地址相等;在value输出中,可以看出二级指针的一级指向-*的值为一级指针的值,也就是变量的地址,而**二级指针的二级指向-就是变量的值与一级指针的指向的值相等。)
(ps:我有个理解就是:n级指针的同级指向就是具体的数据,次级指向就都是地址,比如n-1级指向就是地址。)
二级指针的认识(理解)
二级指针是对地址的地址进行操作:
换句话说,作为二级指针的p,*p指向的(*q)的地址,而**p得到(*p)地址上对应的值。
逻辑分析就是:
**参考量:**
int a=5;
int* p =&a;//一级指针
int** q = &p;//二级指针
**分析**
①p 的值是 a 的地址——所以, *p 指向的是 a的值
②q 的值是 p 的地址——所以, *q 指向的是 p 的地址值
->进而,再取指向,即二级指向*(*q)就相当于*p,所以指向的就是a的值了。
(ps:如果是创建二维数组,就是创建一个一级指针,分配一定的内存空间——然后的该内存段的首地址;再
创建一个二级指针指向这个一级指针,也分配一段内存段——二级指针的值就是该段的首地址。这样,二级控
制一级的存储地址位置,这样每一个二级指针的值,对应者一个特定一级指针——而一级指针本身分配有一个
内存段,这样就有多个内存段——也就相当于二维数组了。——记得二维数组赋值时,要注意是否需要强制转换
哦。)——(代码后边二级指针的操作处跟上)
二级指针的操作
二级指针的操作——最直接的体现就是二维数组的创立了。(至于动态数组什么的,都是一样的操作啦,只需要重复开辟就好)。
代码如下:
#include "iostream"
using namespace std;
//说明一下,动态开辟的内存区属于堆区,需要手动开辟和清除
//(当然了,程序结束也是可自动清除的)
int main()
{
char* pointer_1 = new char[20];//分配字符型数据的内存20个,返回首地址
char** pointer_2=&pointer_1;//创建一个二级指针,默认初始化为一级指针的地址——即二级控制一级(对应二维数组中的关系)
pointer_2 = new char*[3];//二维相当于页
//当前二级指针创建完成,实现开辟内存存储多个1级指针的地址——实现一级指针的控制。
//这样就得到了对应的数据结构关系——3页各20个元素的控制地址。
//在对二级指针进行赋值操作时,实际上是对1级指针的操作
//因为二级指针本身是一级指针的地址,而取下标就对应了*,
//也就是指向二级指针的内容——一级指针的地址(此时的数据类型应该是char*,(字符)指针类型)
//所以当我们向页单位直接进行赋值时,赋给的字符是实际的内容,需要强制转为(char*)指针类型才行
//虽然编译器会提示警告,但是仍然会给你自动调整(添加强制为对应级别的指针类型),但是最好是规范代码的书写
pointer_2[0]=(char*)"Mocha Munch";
//"Mocha Munch"是具体的数据,(char*)转换为地址,才好赋给二级指针(char**)
//我们既然知道指针开辟内存空间后,
//就可以像使用数组类型的方法赋值,只是需要适当的强制转换
//这样——将数据强制转换为1级指针类型数据传给二级指针
//对页操作:pizza_2[1]=(char*)"字符串/字符"
//对行操作:pizza_2[1][10]=(char)'字符'//可以省略char的强制转换
pointer_2[1]=(char*)"2.3";
pointer_2[2]=(char*)"350";
cout << "The value of second pointer :" << endl;//提示,输出的是二级指针的值
cout << pointer_2[0] <<endl;
cout << pointer_2[1] <<endl;
cout << pointer_2[2] <<endl;
delete pointer_1;
delete pointer_2;
return 0;
}
结果显示:(说明对二级指针开辟内存可以实现数组的功能==数组是特殊的指针,即内存连续的指针)
多级指针的拓展
多级指针的扩展和二级指针相对一级指针的扩展是一样的。
毕竟——都是对地址操作——只是映射出一层又一层地址来控制,最后具体的数据还是体现在一级指针对应的地址上的数据。
总结
指针的个人理解:(打个比方,去指定的位置取东西)
一、指针的内容
①一层抽屉里边有10个盒子,每个盒子都有编号。每一个编号就相当于地址,只有找到对应的编号,你才能正确存放进去对的东西或者取出需要的东西。(盒子编号与里边的东西的关系,就是一级指针)——盒子(一级指针),东西(数据)
②如果有很多层这样的抽屉,那么你要找到某一个东西,就要先找到对应层的抽屉,也就是需要在众多抽屉中找到是第几层的抽屉,然后再拉开抽屉,找到对应的盒子编号,就可以取出/放进相应的东西。(抽屉对应的层编号->盒子的编号->盒子里的东西,这样的关系就相当于二级指针。)
——抽屉(二级指针),盒子(一级指针),东西(数据)
③抽屉可能在多个房间里有,确定在哪间房间后,重复②的操作就可以直到东西在哪儿了。(这就相当于是三级指针)——房间(三级指针),抽屉(二级指针),盒子(一级指针),东西(数据)
④房间可能在不同的房屋里,同样的找东西,这样又演化出四级指针。
⑤房屋又属于不同的楼……,这样就的到越来越往后的指针了。
二、指针开辟动态数组
同内容理解一样,只是一级指针(控制一定的内存段(可以含多个数据))往后,每往后一级的指针的值就是上一级指针的地址,反复通过地址控制地址上的内容来实现数据的修改。
比如:
p是一级指针,指向一个数据a,q是二级指针,一级指向是p(也就是int q = &p;q = p;)。*
p开辟10个数据段(连续的内存段),q开辟3个数据段。
p相当于一个10个元素的数组,p本身为这个内存段的首地址,而q控制着p的地址,也就是对这个内存段的首地址进行控制。
由于首地址的更改,必然会导致p代表的数组一整个数据段地址发生改变。
这样下来,q就可以分配p不同的三个地址,而p不同的地址,对应着三条不同的数据段。这样就相当于二维数组——假设有一个数组int b[3][2];,它可以存储的元素个数就是3 * 2。同样的,这时的二级指针也可以实现对3 * 10个地址进行数据分配,这就和数组无二了。
来源:CSDN
作者:笔岸柳影
链接:https://blog.csdn.net/weixin_44604887/article/details/104110974