background image

对 C 越来越熟悉时,你会发现,把与指针搅和在一起的"类型"这个概念分成
"指针的类型"和"指针所指向的类型"两个概念,是精通指针的关键点之一。
我看了不少书,发现有些写得差的书中,就把指针的这两个概念搅在一起了,
所以看起书来前后矛盾,越看越糊涂。
c. 指针的值

 ----或者叫指针所指向的内存区的地址

指针的值是指针本身存储的数值,这个值将被编译器当作一个地址,而
不是一个一般的数值。

在 32 位程序里,所有类型的指针的值都是一个 32 位

整数,因为 32 位程序里内存地址全都是 32 位长。指针所指向的内存区就
是从指针的值所代表的那个内存地址开始,长度为 sizeof(指针所指向的类
型)的一片内存区。

以后,我们说一个指针的值是 XX,就相当于说该指针指

向了以 XX 为首地址的一片内存区域;我们说一个指针指向了某块内存区域,
就相当于说该指针的值是这块内存区域的首地址。
指针所指向的内存区和指针所指向的类型是两个完全不同的概念。在例
一中,指针所指向的类型已经有了,但由于指针还未初始化,所以它所指向
的内存区是不存在的,或者说是无意义的。
以后,每遇到一个指针,都应该问问:这个指针的类型是什么?指针指向
的类型是什么?该指针指向了內存區中的哪里?(重点注意)
d. 指针本身所占据的内存区
指针本身占了多大的内存?你只要用函数 sizeof(指针的类型)测一下
就知道了。在 32 位平台里,指针本身占据了 4 个字节的长度。
指针本身占据的内存这个概念在判断一个指针表达式(后面会解释)是
否是左值时很有用。
[2]、指针的算术运算
指针可以加上或减去一个整数。指针的这种运算的意义和通常的数值的加减
运算的意义是不一样的,

以单元为单位

。例如:

例二:
char a[20];
int *ptr=(int *)a; //强制类型转换并不会改变 a 的类型, 只改变 ptr 由它的值开始的所指向的
//内存区的的长度(sizeof(int)).
ptr++;
在上例中,指针 ptr 的类型是 int*,它指向的类型是 int,它被初始化
为指向整型变量 a。接下来的第 3 句中,指针 ptr 被加了 1,编译器是这样
处理的:它

把指针 ptr 的值加上了 1*sizeof(int)

 ,在 32 位程序中,是被加上

了 4,因为在 32 位程序中,int 占 4 个字节。由于地址是用字节做单位的,
故 ptr 所指向的地址由原来的变量 a 的地址向高地址方向增加了 4 个字节。
由于 char 类型的长度是一个字节,所以,原来 ptr 是指向数组 a 的第 0 号
单元开始的四个字节,此时指向了数组 a 中从第 4 号单元开始的四个字节。
我们可以用一个指针和一个循环来遍历一个数组,看例子:
例三:
int array[20]={0};
int *ptr=array;
for(i=0;i<20;i++)
{

 (*ptr)++;

  //指针所指向的元素的值+1