浅谈指针的类型与类型长度

Author: 明炜 Date: 1995-06-09

        在介绍指针的时候,我们首先接触的往往是指针变量。如int *Pl; float *P2;教科书上的图例清楚地表明了P1和P2的值分别是一个整型和浮点型变量的地址。细心的学员会发现:P1中存的是一个内存地址,P2中存的也是一个内存地址,这两个变量中既然存放的是“相同类型”的信息(都是地址),那么这两个变量是否可以相互赋值,做P1=P2;之类的操作呢?
        答案是否定的。原因也很简单:因为这两个变量的数据类型不同。P1是指向一个整型变量的指针变量,而P2是一个指向浮点型变量的指针变量。严格地说,称P1、P2的类型是指针类型都是错误的。应该说:P1具有指向一个整型变量的指针类型,P2具有指向一个浮点型变量的指针类型。在理解和定义指针变量的时候,除了明确它的值是一个地址以外,还应清楚它的值指向的是一个什么类型的变量。
        数组和指针有十分密切的联系。在定义了int *P, a[10];的情况下,常常会出现这样的语句:P=a;这里的a是数组a[10]的首地址,由于数组在程序开始运行时已被分配好了地址空间,所以它是一个常量。显然,它也有数据类型,从P=a;这个式子,我们可以清楚地看出a的类型与P一致,是指向一个整型变量的指针。好了,知道a指的位置是10个元素的开头,并且它指的是一个整数,我们就可以确定a是指向a[0]的指针,*a即是a[0]。下面我们再看一个例子。
        如定义int b[3][4]; b这个常量的类型是什么呢?C语言中的多维数组是按一维数组来分解后再进行理解的。b[3][4]可被看成一个有3个元素的一维数组,而每个元素又是由4个整型变量组成的一维数组,由此可知:b指的位置是整个二维数组起始处,指的是一个长度为4的整型数组,*b即为b[0]。下面我们进一步来看*b是什么?从上面的分析可知*b就是b[0],它代表一个长度为4,每个元素为整型的一维数组,也就相当于这个一维数组的数组名。对比前面的a[10]可知,*b是一个指向整型变量的指针常量,它指的位置也在二维数组最开始处,指向的是一个整型变量b[0][0]。这里,我们看到b和*b都指在同一位置,但由于它们类型的不同,所指的对象也有所不同。
        从上面的分析可以看到,如要把b赋给一个指针变量,此变量的定义应该是int (*P)[4]。这里的4是必不可少的,它说明所指的整型数组长度为4。另一方面,如果我们进行b+1操作,从指针加法的意义中知道,b+1是在原来b所指向的位置上加上一个类型长度,而b+1的类型与b一致,由于b所指向的是一个长度为4的一维整型数组,其类型长度即为此数组长度,所以b+1指向的位置是b[1][0]的起始处,它的类型也是指向一长度为4的一维整型数组的指针,即指向b[1]的指针。