http://community.youkuaiyun.com/Expert/topic/3149/3149011.xml?temp=3.557986E-02
指针,调皮的精灵。
我们应该这样理解程序代码:一种可以被机器解释执行的数据。那么,我们就可以用统一的观点来看待程序与数据,并将之与指针关联起来。
运行时数据总是要存储在内存中的,以备CPU的不时之需。为了能够快速地访问到数据,计算机内部势必要对内存进行编号--就像门牌号一样。有了明确的编号,CPU就得以快速而准确地访问内存并将数据提取出来。在这里,“内存编号”起到了一种指示地址的作用。可以这样说,任何存在于内存中的东西都拥有地址,以便于对其进行访问。
事实上,这种“内存编号”,或者称“地址”,也是一种数据--毕竟它的数据类型是unsigned integer,当然可以保存在内存中。但是,这种数据有点特殊:它用于指示别的数据的地址,所以保存它的内存区域对应的变量类型也比较特殊:指针类型。顾名思义,指针就是一种具有指向性的变量。理解起来很简单吧?但是越是简单的东西麻烦就越是多,比如……
指针具有两个属性,一个是它的值(就是地址,无论虚实),一个是它的类型(数据类型)。花开两枝,各表一头,咱们先来说说“地址值”。地址值是有大小范围的,其上下限是0~2^n-1,即从0到2的n次幂,其中n是CPU字长,代表了可以寻址的最大范围(比如16位CPU的字长就是n,寻址范围从0到65535,不明白的同学请复习计算机基础)。在不同的硬件平台上,指针变量占用的内存大小与其地址值的范围大小成正比,也即指针变量战胜n个内存位(bit)。
在数学中零是一个很特殊的值,而值为零的地址也是一个特殊的地址。它于用指示地址为零的内存区域--废话--但是操作系统一般会把零地址的区域划为安全区且只能用作捕获越界指针使用。因此将一个指针初始化为零地址是非常安全,而且是必要的(在C的某些编译器中一定要对指针进行初始化才能使用)。一般而言,我们不必在意地址的确切值是多少(实地址,虚地址,逻辑地址,物理地址……),这一切还是扔给编译器去完成好了,毕竟人脑不是编译器:)。
指针的另一个属性是数据类型。实际上这个类型是指针指向的变量的数据类型,而不是指针自身的类型。因为指针的类型是所谓的“用户定义类型”而不是“编译器内建类型”。这个类型有两个作用:1)指示编译器在进行解引用的时候应该从内存中获取几个字节(就是数据类型对应的内存占用字节数),2)以及指示编译器在进行指针类型转换时如何进行类型检查。
通常来说同一个地址可以搭配不同的数据类型,这样通过指针就可以获取位于同一块内存区域中的不同类型数据(或者说,是把同一块内存中的数值解释成不同类型的数据),这就是1)中所说的指针的作用。举个例子:
int a=0xFF00;
char *p=(char *)&a; // 强制类型转换,确保类型匹配(第二点作用的体现,以通过类型检查)
cout << *p << endl; // 指示编译器只获取一个字节数值(第一点作用的体现,以取出正确的数据)
运行结果是0,即只取出了低十六进制位一个字节的数值。
//----------
以上是关于指针专题的前导性知识,希望大家踊跃拍砖。
[C/C++值班室|无锋之刃|2004.7.6 10:36]