第8章 数组
1.数组与指针
数组名是一个指针常量,也就是数组第1个元素的地址。
int a[10]; int b[10]; int *c;
(1) c = & a[0]; &a[0]表示一个指向数组第1个元素的指针。
(2) c=a; 与 c = & a[0]; 等价
(3) b = a; 非法,不能使用赋值符把一个数组的所有元素复制到另一个数组,必须使用一个循环,每次复制一个元素。
(4) a = c; 非法,a是指针常量,而c是指针变量。
2. 下标引用和间接访问完全相同。
array[subscript] <==> *(array + (subscript)) (完全等价)
eg:int array[10];
int *ap=array+2;
(1)ap : <==> array + 2 <==> &array[2]
(2)*ap : <==> array[2] <==> *(array+2)
(3)ap [0] : <==> *(ap + (0)) <==> array[2]
(4)ap + 6 : <==> array + 8 <==> &array[8]
(5)*ap + 6 : <==> array[2]+6
(6)*(ap + 6) : <==> array[8]
(7)ap [6] : <==> array[8]
(8)ap[-1] : <==> array[1]
(9)2[array] : <==> *(2+(array)) <==> *(array + 2)
3. 字符串常量的表示
(1) char message1[ ] = “ hello “; // 初始化一个字符数组的元素
(2) char *message2 = “ hello “; //真正字符串常量
指针常量message2 被初始化为指向这个字符串常量的存储位置。
- 4. 数组元素顺序存储
eg : int array [3][6];
数组:
5. int matrix [3][10];
matrix 这个名字的值是一个指向它第1个元素的指针,所以matrix是一个指向一个包含有10个整型元素的数组的指针。
(1)*(matrix +1) :指向整型的指针。子数组第1个元素地址。
(2)*(matrix +1)+5 :第6个元素的地址。
(3)*(*(matrix + 1) + 5 ) :<==> matrix [1][5]
6.指向数组的指针
int vector[10], *vp = vector; //正确
int matrix[3][10], *mp = matrix; //错误
因为,matrix并不是一个指向整型的指针,而是一个指向整型数组的指针。
int (*p) [10]; //声明一个指向整型数组的指针,p是指向整型数组的指针
int (*p) [10] = matrix; //声明+初始化
指向matrix的第1个整型元素:
(1)int *pi = &matrix [0][0];
(2)int *pi = matrix[0];
7.指针的兼容性
(1)int *pt;
int (*pa) [3];
int ar1 [2] [3];
int ar2 [3] [2];
int **p2;
则:
pt = & ar1 [0] [0] ;
pt = ar1 [0] ;
pt = ar1; // 非法,pt指向一个int数值,而ar1指向由3个int值构成的数组
pa = ar1; //都指向int[3]
pa = ar2; //非法,pa指向3个int构成的数组,而ar2指向2个int构成的数组
p2 = &pt; // 都指向int *
*p2 = ar2 [0]; //*p2类型为指向int的指针,所以和ar2 [0]兼容
p2 = ar2; //非法,p2是指针的指针,ar2是指向由2个int值构成的数组的指针。
因此,p2和ar2类型不同。
(2)将常量或非常量数据的地址赋给指向常量的指针是合法的。只有非常量数据的地址才可以赋给普通指针。
int *p1;
const int *p2;
const int **pp2;
p1 = p2; //非法,把const指针赋值给非const指针
p2 = p1; //合法,把非const指针赋值给const指针,前提是只进行一层间接运算
pp2 = &p1; //非法,把非const指针赋值给const指针