前言:本文将讲解指针的定义、指针变量和普通变量的本质区别、一级指针和二级指针的关系以及如何通过二级指针修改一级指针所指向的内存。文末还附加了两个实例,帮助读者加深对二级指针的理解。本文试图通过图表的方式,通俗地讲解指针和二级指针,让读者对此有深入的理解。阅读本文大概需要15分钟的时间。

1、指针的定义:

int a = 1; //普通变量的定义
int *pA = &a; //指针的定义或者
int *pA = NULL;
pA = &a;

符号&表示“取址符”,也就是获取上面的变量a所在内存空间的地址。
从上面指针的第二种定义中就可以看出,变量pA的值等于变量a的内存地址。星号*的作用是表明变量pA是一个指针变量。那么,普通变量和指针变量的区别是什么呢?

2、普通变量和指针变量

普通变量:(变量名字name,变量值value,变量的内存地址addr)
指针变量:(变量名字name,变量值value,变量的内存地址addr)

从表面上看,普通变量和指针变量没有多大区别。实质上的区别是:指针变量的变量值value 存储的是一个用16进制表示的32位内存地址,比如00A6F790。而普通变量的变量值value 所存储的内容没有限制。还有,指针变量能够根据变量值value中的内存地址获取到该地址所对应的值(假设指针变量名为p,通过*p来获取)。具体看下面的关系图:


其中,上图中变量的定义为:

int commonVar = 12;///
string str = "hello";
string * poiterVar = &str;

poiterVar = “00ER343O”
*poiterVar = “hello”;
所以,指针变量和普通变量没有太大区别。

###3、 一级指针和二级指针的关系

那么,对于指针的指针呢?


上图中两个指针的定义为:

string str = "hello";
string *poiterVar1 = &str;
string **poiterVar2 = &poiterVar1;

暂时不要考虑*星号,避免被星号搞混了。星号的作用有两个,一是在指针定义的时候表明该变量是指针变量以及是几级指针(有几个星号就表示几级),二是能够通过指针变量所指向的内存地址(或者说上图中Value的值)来获取对应内存的内容。比如上图中的poiterVar1通过Value = 00ER343O来获取hello,即*poiterVar1

从上图中还可以看出,一级指针poiterVar1和二级指针poiterVar2没有什么区别。如果非要说出一点区别的话,就是在指针定义的时候,后者多加了一个*星号。

指针变量修改所指向的内容的时候,因为指针指向的是其内存地址,所以,就相当于把该内存中的内容修改了。这一点是指针强大的原因所在,也是它存在的原因。


4、实例讲解1


上图中两个指针的定义为:

string *poiterVar1 = NULL;
string **poiterVar2 = &poiterVar1;

指针变量poiterVar1初始化的时候指向了NULL。可以通过poiterVar2修改poiterVar1,让它指向一个非NULL的内容吗? 是可以的。怎么做到呢?
问题可以转换为:让pointerVar1中的Value等于一个有效的内存地址。具体怎么做呢?因为poiterVar2拥有poiterVar1的内存地址,所以,可以通过poiterVar2来修改poiterVar2变量中的值(也就是它的Value)。具体如下:

string *poiterVar1 = NULL;
string **poiterVar2 = &poiterVar1;string str = "hello";/*
if (*poiterVar2 == poiterVar1) cout << "*poiterVar2 == poiterVar1" << endl;
else cout << "*poiterVar2 != poiterVar1" << endl;
*/*poiterVar2 = &str;cout << *poiterVar1 << endl;//执行结果
//*poiterVar2 == poiterVar1
//hello

上面代码中,*poiterVar2 代表poiterVar1的Value,把str的内存地址赋值给*poiterVar2 就可以了。


5、实例讲解2

本实例和第一个实例基本相同,只是把string类型变成了自定义的Teacher类型。开始的时候Teacher类型的指针为NULL,通过一个二级指针让一级指针指向一个有效的内存空间。也是指针的指针的问题,一级指针是teacherObj,二级指针是pTeacher(函数的参数)。

在代码中它们的关系可以表示为:

Teacher *teacherObj = NULL;
Teacher **pTeacher = &teacherObj;

所以,这个实例和第一个实例是一样的。

#include <iostream>
#include <string>
using namespace std;struct Teacher {int age;char* name;
};int getTeacher(Teacher **pTeacher){if (pTeacher == nullptr)return -1;Teacher * tmpTeacher = (Teacher*)malloc(sizeof(Teacher));if (tmpTeacher == nullptr) return -1;tmpTeacher->age = 32;tmpTeacher->name = "Liangyihuai";*pTeacher = tmpTeacher; //*pTeacher就代表一级指针的value值。return 1;
}int main() {Teacher *teacherObj = NULL;getTeacher(&teacherObj);cout << teacherObj->age << " " << teacherObj->name << endl;system("pause");return 0;
}

拓展:
上面的getTeacher方法也可以写成:

int getTeacher2(Teacher* &pTeacher) {Teacher * tmpTeacher = (Teacher*)malloc(sizeof(Teacher));if (tmpTeacher == nullptr)return -1;tmpTeacher->age = 32;tmpTeacher->name = "Liangyihuai";pTeacher = tmpTeacher;return 1;
}//在main函数中:
//Teacher *teacherObj = NULL;
//getTeacher2(teacherObj);

其中引用pTeacher表示teacherObj,也就是pTeacher是teacherObj的一个别名,而teacherObj是一个指针变量,所以,让pTeacher等于一个有效的内存空间就可以了。

6、总结:

本文讲解了指针变量和普通变量的区别。分析了二级指针和一级指针的区别和本质,以及如何使用二级指针修改一级指针所指向的内存空间。如果有误,欢迎指教。

深入理解指针以及二级指针(指针的指针)相关推荐

  1. 深入理解C语言-二级指针三种内存模型

    二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {&quo ...

  2. 指针与二级指针的理解与应用

    指针 一.指针的概念 一切都是内存地址 C语言用变量来存储数据,用函数来定义一段可以重复使用的代码,它们最终都要放到内存中才能供 CPU 使用. 数据和代码都以二进制的形式存储在内存中,计算机无法从格 ...

  3. 指针数组,数组指针,指针函数,函数指针,二级指针详解

    先看个简单的:char *p,这定义了一个指针,指针指向的数据类型是字符型,char  *(p)定义了一个指针P: char *p[4], 为指针数组,由于[]的优先级高于*,所以p先和[]结合,p[ ...

  4. 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 二级指针排序 | 通过 交换指针指向的内存数据 方式进行排序 )

    文章目录 一.二维指针 排序 ( 通过 交换指针指向的内存数据 方式进行排序 ) 二.完整代码示例 一.二维指针 排序 ( 通过 交换指针指向的内存数据 方式进行排序 ) 在上一篇博客 [C 语言]二 ...

  5. 【C 语言】二级指针作为输入 ( 自定义二级指针内存 | 二级指针 排序 | 通过 交换指针方式 进行排序 )

    文章目录 一.二维指针 排序 ( 通过 交换指针方式 进行排序 ) 二.完整代码示例 一.二维指针 排序 ( 通过 交换指针方式 进行排序 ) 在上一篇博客 [C 语言]二级指针作为输入 ( 二维指针 ...

  6. 全国计算机二级考试c语言指针,全国计算机二级考试C语言 指针精讲课件.ppt

    全国计算机二级考试C语言 指针精讲课件 第七章:指 针;第一节:指针概述;如:执行以下说明语句后: int a=3,b=4; float c=4.5,d=8.6; char e='x',f='y';其 ...

  7. (C++)函数参数传递中的一级指针和二级指针

    主要内容: 1.一级指针和二级指针 2.函数指针传递的例子 3.什么时候需要传递二级指针? 4.二级指针在链表中的使用 1.一级指针和二级指针 一级指针:即我们一般说的指针,就是内存地址; 二级指针: ...

  8. 函数参数的传递问题(一级指针和二级指针)

    函数参数的传递问题(一级指针和二级指针) [转] 原以为自己对指针掌握了,却还是对这个问题不太明白.请教!   程序1:   void  myMalloc(char  *s)  //我想在函数中分配内 ...

  9. C语言:结构体中一级指针和二级指针的创建与释放示例

    http://blog.csdn.net/Bixiwen_liu/article/details/53610952 这几天把C语言巩固了一下,作为一门最基本的编程语言,C语言还是相当基础和非常重要的, ...

最新文章

  1. yii2.0错误:Exception yii\base\InvalidConfigException with message
  2. mybatis jar包_Java修行第039天---Mybatis框架
  3. 【Tools】TeamViewer安装教程
  4. 分布式事务中的CAP理论
  5. Linux 程 序 员 失 业 警 告
  6. java关闭文件句柄_java-JAI关闭文件句柄为时过早吗?
  7. 如何训练自己的编程思路
  8. 论软件开发中的可信赖的工作
  9. 20个最漂亮的基于WordPress的企业网站
  10. 网易云音乐服务器code521,宝塔面板部署网易云音乐无版权服务器
  11. 联想如何在桌面显示计算机和网络图标,联想电脑桌面图标字体变小怎么办
  12. 微警务:网上公安服务一键开启
  13. web请求报出 “超过了最大请求长度”
  14. 《数据结构》第十一篇、线性表中的链式存储结构--循环链表
  15. Bit-Vector框架(1) — Reaching Definition Analysis
  16. 集成 Jenkins 和 TestNG 实现自助式自动化测试平台
  17. Make Product Equal One(思维)
  18. 【Pytorch Lighting】第 5 章:时间序列模型
  19. 从西安到深圳——一路向南
  20. ACM-ICPC 2018 南京赛区网络预赛 E. AC Challenge(状压dp)

热门文章

  1. 扩展源_Ubuntu14版本下无法使用php7.2版本的bcmath扩展
  2. sqlalchemy安装以及使用_电子皮带秤的安装使用条件以及对输送机的要求
  3. app 404 html,静态页面错误404(Flask框架)
  4. matlab金属槽有限差分法程序,有限差分法MATLAB程序
  5. 在深谈TCP/IP三步握手四步挥手原理及衍生问题—长文解剖IP
  6. Android左右滑屏遇到listview问题解决
  7. mysql 插入表情符号 '\xF0\x9F\x8D\xB0/...' 报错的解决方法
  8. delphi创建和读取xml(xml简单操作举例)
  9. robotium常用方法
  10. Responsive设计——meta标签