文章会在文末更新!

关于指针是什么,很多教材已经作出了定义,大多数都会定义为“存放变量内存地址的变量”。从这句话中我觉得除了让我知道这个定义有11个字以外,其他就没什么用了。我个人觉得要理解指针,不是光光说一下是变量的地址就万事大吉了,而是要从多个属性来解释指针,为此,我个人总结了一个所谓的多维属性法来理解指针。

另外,为了能把指针说清楚,我认为关键不在于用苦涩的文字描述,而在于以示意图的形式描述清楚指针的概念。我接下来就准备用我的多维属性法,加上画几张图,和一些伪代码,尽量说清楚指针是什么。绘图水平有限,技术水平也有限,欢迎多批评。

1.要说清楚指针是什么之前,先来看看如何从多维属性来理解普通变量,以及普通变量在内存中是什么样儿的。

比如现在有个整型变量:int a = 1;也就是说整型变量a的值是1,在内存中的存放如示意图1所示:

示意图1

相信朋友们对这张图无任何异议,很简单嘛,a就是1,1就是a嘛。好了,我可以提炼出变量a的三个属性出来,分别是有用数据的名字,有用数据的值,有用数据的类型。

有用数据的名字,就是“a”;

有用数据的值,就是“1”;

有用数据的类型,就是“int”;

我之所以用“有用数据”这四个字来描述,是因为程序代码中会经常用到变量“a”,以及它的值“1”,还有它的类型“int”,那不就是有用的嘛,所以我就“有用数据”来描述变量a的三个属性。好了,我用下面的表示法来表示变量a的这三个属性:

变量a=(有用数据的名字,有用数据的值,有用数据的类型)



好了,假设变量a的地址是“0x380fe0”,则示意图2是从变量a的地址的角度来看变量a在内存中的存放形式:

示意图2

在图2中,我标记出变量a的地址是16进制的0x380fe0,a为1,也就是在内存地址为“0x380fe0”的地方放了一个值1。用C语言表示地址的术语来说就是“&a”等于“380fe0”。“&”是表示变量地址的意思。这张图相信朋友们也没有什么异议,对吧,都是很直观的东西。好,我又可以提炼出变量a的第4个属性,叫做“有用数据的地址”,也就是“&a”啦。至此,变量a的四个属性都齐全啦,如下:

变量a=(有用数据的地址,有用数据的名字,有用数据的值,有用数据的类型),具体到本例,就是:

变量a=(0x380fe0,a,1,int)



2.从四个属性来说明一般的整型变量在内存中的样儿,好了,下面我要放大招儿了,再说说从四个属性来理解指针变量,以及指针变量在内存中的样儿。

我定义一个指针变量:

int *p = NULL;

p = 0x380fe0;

这两句代码朋友们也一定看的懂的,就是一个指针变量p的值用16进制来表示就是“0x380fe0”,这正好是变量a的地址。p在内存中的表示如下示意图3:

示意图3

示意图3跟整型变量a的示意图1没任何区别,我也可以说p就是0x380fe0,0x380fe0就是p,跟变量a就是1,1就是a是一个道理。好,这里我提炼出指针p的第一个属性,叫做“指针自己的值”,指针变量p的值是0x380fe0,可不就是自己的值嘛!用如下表示发来表示就是:

指针p=(指针自己的值)



到此为止,朋友们应该都是无异议的,好,下面再来看“*p”是什么东西,如下示意图4所示:

示意图4

指针变量p前面加个“*”就变成了“*p”。很多教材会说“指针变量p指向的值是1”,这说了等于没说,谁看的懂。加了星号后,*p就是a的等价物了,是a的别名了,也就是*p就是a,a就是*p。这样说大家应该都会看懂吧。好了,这里我可以提炼出指针变量p的剩余三个属性了,分别叫做”与星号结合名“,”有用数据的值“,”有用数据的类型“。

与星号结合名:就是”*“与指针p结合,变成*p;

有用数据的值:就是1;跟变量a的第三个属性一样;

有用数据的类型,就是int;跟变量a的第四个属性一样。

这样指针变量p的四个属性也齐全了,如下:

指针变量p=(指针自己的值,与星号结合名,有用数据的值,有用数据的类型)。在本例就是:

指针变量p=(0x380fe0,*p,1,int)。



3. 用变量a的四个属性与指针变量p的四个属性对比,一下子就能看出指针的本质了。

我整理下上述的伪代码:

int a = 1;//假设变量a的地址是0x380fe0

int *p = NULL;

p = &a;

再用我说的多维属性法分别来表示整型变量a和指针变量p,分别如下:

整型变量a=(有用数据的地址,有用数据的名字,有用数据的值,有用数据的类型)



指针变量p=(指针自己的值,与星号结合名,有用数据的值,有用数据的类型)




在本例中,它们各自的属性就是:

整型变量a=(&a的值,a,1,int)



指针变量p=(p的值,*p,1,int)


再细一点,就是:

整型变量a=(0x380fe0,a,1,int)



指针变量p=(0x380fe0,*p,1,int)


看出来了吗?看出来了吗》看出来了吗?它们的四个属性的含义是一一等价的,具体来说就是:

&a“ 就是 ”p“.

a“就是 ”*p

1“ 就是 ”1

int“ 就是 ”int

这才是理解指针p的本质关键所在。

关于”&a“ 就是 ”p“我再说两句。同样是表示地址,”&a“是用了”&“和”a“两个字符的组合来表示的,而”p“就用了一个字符”p"来表示,这种字符数量上的不一致导致了很多人学指针时会犯晕!

关于”a“就是 ”*p“我也说两句。同样是表示整型变量的名字,这次”a“就用了一个字符”a“来表示,而”*p“用了字符“*”和”p"两个字符来表示,又是这种字符数量上的不一致又导致了很多人学指针时会犯晕!



说了这么多废话,其实就是为了说明指针变量的四个属性表示法,建议记住这四个属性表示法,以及与一般整型变量、字符变量等一般变量类型的四个属性之间的等价关系。当然了,别指望记住这四个属性你就理解指针了,该学习的还是要学习,该多写代码的还是要多写代码,我只是希望你记住四个属性后再学习指针时,不至于被指针碾压的那么惨。

============================= 2017-2-7 更新 ==============================

对于第二个属性,在本文中,就是一个“*”和“p”的结合“*p”,别看它是由两个字符组成的,其实本质上就是变量“a”,因此从这一个属性开始,你完全可以用一般的整型变量“a”来思考问题了,也就是直接将“*p”看做“a”,后面的第3个属性就是这个“a”的值“1”,第4个属性就是“a”的类型“int”。记住,从第2个属性开始,就与指针p没有任何关联了,你全部使用整型变量a的思维去思考问题。

从四个属性的角度来理解C语言的指针也许会更好理解的更多相关文章

  1. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  2. 理解C语言中指针的声明以及复杂声明的语法

    昨天刚把<C程序设计语言>中"指针与数组"章节读完,最终把心中的疑惑彻底解开了.如今记录下我对指针声明的理解.顺便说下怎样在C语言中创建复杂声明以及读懂复杂声明. 本文 ...

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

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

  4. 深入理解C语言函数指针(转)

    本文转自:http://www.cnblogs.com/windlaughing/archive/2013/04/10/3012012.html 示例1: void myFun(int x); //声 ...

  5. 深入理解C语言-函数指针

    函数指针在C++中有着重要的应用,函数的函数名其本质就是代表一个地址,这个地址叫做函数入口,得到这个地址就可以对这个函数进行各种操作. 函数类型基础 函数三要素: 名称.参数.返回值 C语言中的函数有 ...

  6. position的四个属性值

    1.relative2.absolute3.fixed4.static下面分别讲述这四个属性. <div id="parent"> <div id="s ...

  7. jsp四种属性范围

    在JSP提供了四种属性的保存范围.所谓的属性保存范围,指的就是一个设置的对象,可以在多个页面中保存并可以继续使用.它们分别是:page.request.session.appliction. 1.pa ...

  8. ORACLE中CONSTRAINT的四对属性

    ORACLE中CONSTRAINT的四对属性 summary:在data migrate时,某些表的约束总是困扰着我们,让我们的migratet举步维艰,怎样利用约束本身的属性来处理这些问题呢?本文具 ...

  9. 深入理解c语言_从编译器的角度考虑问题_纪念Dennis Ritchie先生

    开源中国: Dennis Ritchie教授过世了,他发明了C语言,一个影响深远并彻底改变世界的计算机语言.一门经历40多年的到今天还长盛不训的语言,今天很多语言都受到C的影 响,C++,Java,C ...

随机推荐

  1. 教你干掉win10全家桶

    原文: 教你干掉win10全家桶 这些并不好用的自带应用例如:groove音乐,相片,股票……一直占据着我们的默认应用.如果它们是一直静静的躺在那里还好,最多不用就是了.当我们想要浏览图片或者看视频的 ...

  2. 分配粒度和内存页面大小(x86处理器平台的分配粒度是64K,内存页是4K,所以section都是0x1000对齐,硬盘扇区大小是512字节,所以PE文件默认文件对齐是0x200)

    分配粒度和内存页面大小 x86处理器平台的分配粒度是64K,32位CPU的内存页面大小是4K,64位是8K,保留内存地址空间总是要和分配粒度对齐.一个分配粒度里包含16个内存页面. 这是个概念,具体不 ...

  3. Markdown 入门

    一. Markdown语法的简要规则 标题 标题是非常重要的一个标记,一段文字标记为标题,只需要在文字前加 #.具体可以支持到1到6个# 1 2 3 4 # 一级标题 ## 二级标题 ### 三级标题 ...

  4. 获取UWP配置文件中的版本信息

    原文:获取UWP配置文件中的版本信息 在一般的软件中,我们都会显示当前软件的版本信息.以前作者都是在发版的时候修改一下UWP的配置文件中的版本信息和软件中的版本信息.但是每次这样很麻烦,有时间忘记修改 ...

  5. extjs grid 复选框选择事件

    开发中需求是统计选择的行数,所以要监控checkbox的选择事件包括表头的全选事件 遇到的问题就不赘述了 方案是监控grid的复选框和行加载时绑定事件 baseView: DBEN.controls. ...

  6. 如何作为一个优秀的ERP实施顾问

    原文地址:如何作为一个优秀的ERP实施顾问作者:天思软件 作一个优秀的ERP实施顾问无论是天思.金蝶,用友,还是其他业务软件.实施顾问的发展道路都差不多. 1.初级实施顾问,中级实施顾问,高级实施顾问 ...

  7. VCL比MFC好在哪里

    作者:刘国华链接:https://www.zhihu.com/question/35218485/answer/118472021来源:知乎著作权归作者所有,转载请联系作者获得授权. 从使用感受而言, ...

  8. 认识Docker

      以下是个人学习过程中所记,仅作为学习经历和备忘,有问题不负责,但可以交流和探讨. 1 什么是Docker?   在Docker的官网,Docker的设计师们对Docker的定义是:   Docke ...

  9. 关于 win32 下磁盘的遍历方法

    最近要写个在线专杀的东东,虽然是专杀(本来只要清除几个特定的文件和杀几个特定的进程,然后把用户的注册表恢复正常,很多病毒木马最喜欢干的一件事情就是写 映像劫持 然后机器一重启,安全相关的软件全部玩完了 ...

  10. kafka笔记6

    我们讨论可靠性时,一般使用保证这个词,它是确保系统在各种不同的环境下能够发生一致的行为.Kafka可以在哪些方面作出保证呢? 1.Kafka可以保证分区消息的顺序 2.只有消息被写入分区的所有同步副本 ...