(2)当两个指针指向同一个数组的元素时,允许两个指针作减法运算。其绝对值等于两指针所指数组元素之间相差的元素个数。如表达式&a[4O]-&a[0]的值为40。 (3)当两个指针指向同一个数组的元素时,这两个指针可以作关系比较(<,<=, ==,>,>=,!=)。若两指针p和q指向同一个数组的元素,则p==q为真表示p,q指向数组的同一个元素;若p 利用运算符*可引用指针所指对象,*(a+i)表示引用a+i所指向的数组元素a[i] 。这样。(a+i)就是 a[i]。对于指向数组元素的指针变量p,若p指向a[10],*(p+i)表示引用p+i所指向的数组元素 a[10+i]。 与用数组名和下桥引用数组元素的标记法相一致,指向数组元素的指针变量也可带下标引用数组的元素,即*(p+i)也可写成p[i] 。但若p=&a[10],则p[i]引用的是a[10+i],p[2]引用的是a[8]。 综上所述,引用数组元素有以下多种形式: (1)用数组元素的下标引用数组元素,如 a[5]。 (2)利用数组名表达式的值是数组首元素指针的约定,可利用指针表达式间接引用数组元素,如*(a+i) 。 (3)利用指向数组元素的指针变量,用它构成指向数组元素的指针表达式,并用该表达式引用数组元素。如*(p+i)或p[i]。 这里要强调指出用数组名a表达数组元素指针与用指向数组元素的指针p来表达数组元素的指针,在实际应用上的区别:p是变量,其值可改变,如p++;而数组名a只代表数组a的首元素的指针,它是不可改变的,程序只能把它作为常量使用。 3.指向字符串的指针变目 通常所说的字符串指针就是指向字符率某字符的字符指针。因字符率存储于字符数组中,所以字符串指针也就是指向数组元素的指针。 为程序中引入的字符串常量提供存储空间有两种方法。一是把字符率常量存放在一个字符数组中。例如: char s[]=“I am a string.”; 数组s共有15个元素,其中 s[14] 为‘\0' 字符。对于这种情况,编译程序根据字符串常量所需的字节数为字符数组分配存储,并把字符串复写到数组中,即对数组初始化。另一种方法是由编译系统将字符串常量与程序中出现的其它常量一起存放在常量存储区中。程序为了能访问存于常量存储区中的字符串常量,可用一个字符指针指向它的第一个字符。当字符串常量出现在表达式中时,系统将字符率常量放入常量存储区,而把表达式转换成字符指针,指向该字符串常量的第一个字符。因此,可在定义字符指针变量时给它初始化指向某字符串常量,或用字符申常量给字符指针变量赋值,这两种方法都使字符指针指向字符串常量的第一个字符。例如: char *cp1,*cp2=“I am a string”;/*定义字符指针变量,并赋初值*/ cp1=“Another string”;/* 先定义字符指针变量,然后按需要赋初值*/ 上述代码使字符指针变量cp2指向字符率常量“I am a string”的第一个字符I,使cpl指向字符串常量“Another string”的第一个字符 A。 4.指向二维数组中的某个一维数组的指针变量 如有一个二维数组,且指针变量所指的是二维数组中的一整行,则指针变量另有一些很有意义的性质。设有二维数组为 int a[3][4]={{1,2,3,4},{5,6,7,8 },{ 9,10,11,12 }}; 这里,数组a有3行4列。按行来看数组a,数组a有三个元素,分别为a[0],a[1],a[2]。它们又分别是一个一维数组,各有4个元素。例如,a[0]所代表的一维数组为 a[0][0] 、a[0][l] 、a[0]p[2], a[0][3]。 一维数组名表达式的值是数组首元素(下标为0)的地址,二维数组名a表达式是a的首行a[0]的地址。一般地,a+i可以看作二维数组a的第i+1行的首地址。 因二维数组a能用a[0].a[1]、a[2] 分别表示它的各行,所以a[0]能表示用a[0]标记的 a的第一行的首元素 a[0][0] 的地址;a[1] 能表示用 a[l] 标记的 a的第二行的首元素 a[l][0] 的地址。一般地,a[i]能表示用 a[i]标记的a的第i+1行的首元素a[i][0]的地址。由于数组的开始地址与数组首元素的地址相同,这样,a+i与a[i]应有相同的值,但它们的意义不同,a+i表示用a[i]标记的a的第i+1行的首地址,a[i]表示用a[i]标记的a的第i+l行的首元素a[i][0]的地址。另外,因a[i]可写成*(a+i),所以a+i与*(a+i)也有不同意义,而值相等。a[i]或*(a+i) 表示二维数组a的元素a[i][0]的地址,即&a[i][0]。根据地址运算规则,a[i]+j即代表数组a的元素a[i][j]的地址,即&a[i][j]。因a[i]与*(a+i)等价,所以*(a+i) +j也与&a[i][j]等价。 |