很多初学者弄不清指针和数组到底有什么样的关系。我现在就告诉你:他们之间没有
任何关系!只是他们经常穿着相似的衣服来逗你玩罢了。
指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址。
指针可以指向任何地方,但是不是任何地方你都能通过这个指针变量访问到。
数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型
和个数。数组可以存任何类型的数据,但不能存函数。
--------------------------------------------------------------------
下面我们就详细讨论讨论它们之间似是而非的一些特点。例如,函数内部有如下定义:
A),char *p = “abcdef”;
B),char a[] = “123456”;
1,以指针的形式访问和以下标的形式访问指针
例子A)定义了一个指针变量p,p 本身在栈上占4 个byte,p 里存储的是一块内存的首
地址。这块内存在静态区,其空间大小为7 个byte,这块内存也没有名字。对这块内存的访
问完全是匿名的访问。比如现在需要读取字符‘e’,我们有两种方式:
1),以指针的形式:*(p+4)。先取出p 里存储的地址值,假设为0x0000FF00,然后加
上4 个字符的偏移量,得到新的地址0x0000FF04。然后取出0x0000FF04 地址上的值。
2),以下标的形式:p[4]。编译器总是把以下标的形式的操作解析为以指针的形式的操
作。p[4]这个操作会被解析成:先取出p 里存储的地址值,然后加上中括号中4 个元素的偏
移量,计算出新的地址,然后从新的地址中取出值。也就是说以下标的形式访问在本质上
与以指针的形式访问没有区别,只是写法上不同罢了。
2,以指针的形式访问和以下标的形式访问数组
例子B)定义了一个数组a,a 拥有7 个char 类型的元素,其空间大小为7。数组a 本身
在栈上面。对a 的元素的访问必须先根据数组的名字a 找到数组首元素的首地址,然后根据
偏移量找到相应的值。这是一种典型的“具名+匿名”访问。比如现在需要读取字符‘5’,
我们有两种方式:
1),以指针的形式:*(a+4)。a 这时候代表的是数组首元素的首地址,假设为0x0000FF00,
然后加上4 个字符的偏移量,得到新的地址0x0000FF04。然后取出0x0000FF04 地址上的
值。
2),以下标的形式:a[4]。编译器总是把以下标的形式的操作解析为以指针的形式的操
作。a[4]这个操作会被解析成:a 作为数组首元素的首地址,然后加上中括号中4 个元素的
偏移量,计算出新的地址,然后从新的地址中取出值。
由上面的分析,我们可以看到,指针和数组根本就是两个完全不一样的东西。只是它们
都可以“以指针形式”或“以下标形式”进行访问。一个是完全的匿名访问,一个是典型
的具名+匿名访问。一定要注意的是这个“以XXX 的形式的访问”这种表达方式。
另外一个需要强调的是:上面所说的偏移量4 代表的是4 个元素,而不是4 个byte。只
不过这里刚好是char 类型数据1 个字符的大小就为1 个byte。记住这个偏移量的单位是元
素的个数而不是byte 数,在计算新地址时千万别弄错了。