指针C++中极其重要的概念,如果说某汪在华语乐坛占据了半壁江山,那么指针也是支撑C++众多高级特性的一双有力的大手。本文简要说明C++中指针的定义及指针类型的判断,其中指针类型的判断往往是初学者大的障碍,但这也是需要重点掌握的基础技能
  一、什么是指针 指针的定义
  从各种教科书上大同小异的定义来看,指针是保存其他变量的地址的变量。要想弄懂这个定义,我们需要先搞清楚两个概念:变量、变量的地址。
  变量、变量的地址 (1)变量的引入
  变量是用于存储某一数值的“容器”(“容器”这一词在C++和其他领域中是专业术语,这里只是用于比喻,不要把这个词当成对变量的术语,牢记!),我们在计算机中编程时,总体来看都是“输入——计算——输出”这一套路,所以往往会有大量的数据,如果程序中全部的数据都是使用字面常量的方式来记录,那么先不说可实现性,光光是程序的编写和维护是一件几乎不可能的事了,所以从BCPL和B语言之后(准确地说是C语言后),正式有了变量的概念。程序员只需要定义好某种类型的变量,可以存储对应类型的数据,而不需再再像在无类型语言里那样关心数据在内存中是如何存储的了。
  (2)逻辑上的内存模型
  这里所说的内存模型是高级语言程序员脑中的内存模型,实际上并不存在;内存的物理模型不需要高级语言的初学者考虑,故不在此讨论
  程序运行在内存中,数据和指令都加载进内存中(然而实际上并不是这么理想,在之后的文章中我会再介绍操作系统对内存的管理),所以为了让访问内存的设备能准确地定位到某一处,内存的每一处都分配了一个的数值,相当于身份证号,称作地址。内存地址是二进制的数值。32位机的寻址能力是能在由32位标识的内存地址中进行定位,所以内存大小被限制在4GB。
  地址这一词与人类社会的门牌号很像,人住在屋子里,而屋子有一个编号,人看作数据,屋子是存储“人”这一类型的变量,而门牌号是变量的地址。
  指针的作用
  看了以上这么多的文字,那么指针的类比概念也很好理解了,不过到此我们需要回答一个问题:为什么需要指针?通过指针来操作变量还是一个二级的操作,这不会显得很麻烦吗?
  是的,通过指针我们确实比直接操作变量多做了工作,但恰恰是指针,也给了程序员直接操作内存的机会,因为直接操作内存比操作变量在时间上要快上很多,这也是为什么C++程序运行的效率高的原因之一。
  指针的类型
  指针(pointer)的全名其实是指针变量,也是说指针也是变量。既然是变量,那么很自然的也有类型这一问题。C++是强类型的静态语言,某一种类型的变量只能存储其对应类型的数据,指针也不例外。通常,当某一类型指针保存着其对应类型的地址时,我们说“这个指针指向了那个变量”。
  二、指针的类型
  正文从这开始。
  把指针考虑成变量,所以我们从基本的变量(以整型为例)的定义开始分析。
  int p;
  p是一个整型变量。
  int *p;
  p是一个指向整型变量的指针。
  int p[SIZE];
  p是一个数组,数组中有SIZE个元素,每个元素都是整型。
  int *p[SIZE];
  从这里开始变得有趣了。
  对于这种“复杂”类型的定义,有一种方法是从中间开始读,根据运算符优先级向两边扩展。
  p是一个数组(先与定义数组的下标运算符结合,因为下标运算符[]的优先级高于解引用运算符*),数组中有SIZE个元素,然后与*结合,数组中的元素都是指针,后看int,即指针指向int。所以,把以上的分析过程连起来,是,p是一个由SIZE个指向整型的指针构成的数组。
  int (*p)[SIZE];
  这里我们会开始简单看到()运算符的其中一个作用。
  首先,从p开始寻找优先级比*高的运算符——是的,()在这里的意义和数学中的小括号是一样的,都是用于强行改变运算优先级的运算符。所以,因为有(),p先与*结合,p是一个指针,然后再与[]结合,p这个指针指向一个有SIZE个元素的数组,后,看int,即,p是一个指向由SIZE个整型元素构成的数组的指针。