一、指针数组
char *p[n] ———数组中的元素存放的是指针(地址)。
eg:
char * name[] = {“Mon”, “Jan”, “Feb”, “Mar”};
char *a[4] = name;
【释义】:a[0]存放的是字符串”Mon”的首地址,其他类推。
二、数组指针
char (*p)[n]———指针指向的对象时数组(p指向的是具有n个元素的一维字符数组)
1)指向数组元素的指针变量
1.1用指针变量输出二维数组元素的值
1 #include <stdio.h>
2
3 int main(void){
4 int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
5 int *p;
6 for(p = a[0]; p < a[0] + 12; p++){
7 printf("%4d", *p);
8 }
9 printf("\n");
10 return 0;
11 }
计算a[i][j]在数组中相对位置的计算公式:(二维n*m数组)i*m + j
- 开始指针变量p指向a[0][0]即 p =&a[0][0]
- (p + 2*4 + 3 ) == &a[2][3]
- *(p + 2*4 +3) == a[2][3]
- &a[i][j] == &a[0][0] +I *m +j
2)指针变量指向由m个元素组成的一维数组(指向行的)
Int a[3][4];
Int (*p)[4] = a;
p,a--------> p+1------->
| a[0] |
a[1] | |
a[2] |
【释义】P不是指向整型的变量,而是指向一个包含m个元素的一位数组;
如果p指向a[0],即p = &a[0], 则p+1指向a[1], 即p的增值一一位数组的长度为单位。
三、特殊情况(指针值相同,但含义不同,也即指针指向的对象不同)
对于二维数组int a[3][4]
&a[i] //&a[i]或a+1指向行
a[i] (&a[i][0]) //a[i]或*(a+i)指向列
它们具有同一地址值,但指向的对象是不同的,指针的类型是不同的。
四、实际例子(打印二维数组)
#include <stdio.h>
int main(void){
int a[4][5] = { {1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15},{16,17,18,19,20}};
int (*p)[5] = &a[0];
int i, j;
for(j = 0; j < 4; j++){
for(i = 0; i < 5; i++){
printf("%4d", *(*p + i));
}
p++;
printf("\n");
}
int (*q)[4];
q = (int (*)[4])a;
for(j = 0; j < 5; j++){
for(i = 0; i < 4; i++){
printf("%4d", *(*q + i));
}
q++;
printf("\n");
}
return 0;
}
输出结果:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
17 18 19 20
五、二维数组与二级指针无必然联系
一个反例
int main(void)
{
char a[] = {1,2,3,4,5,6,7};
char (*p)[7] = &a;
printf("%d\n", *(*(p+1) - 2)); //6
}
【说明】
1、(p +1)指向下一个数组
2、&a[5] == *(p + 1) – 2 指向a[5]
3、*( *(p + 1) – 2 ) == a[5] == 6
p—》a | 1 2 . . 7 |
p+1—》b |
|
六、其他杂项
一个关于类型转换以及指针相减的例子:
int main(void){
int a[100];
printf("%d\n", &a[20] - a); //20
printf("%d\n", (int *)&a[20] - (int *)a); //20
printf("%d\n", (int)&a[20] - (int )a); //80
printf("%d\n", (char *)&a[20] - (char *)a);//80
printf("%d\n", (char)&a[20] - (char)a); //80
}
输出结果:
20
20
80
80
80
更复杂一点
int main(void)
{
char b[][4] = {1,2,3,4,5,6,7,8,9};
char (*q)[4] = b;
char (*n)[3][4] = &b;
printf("%d\n", *(*(*n + 1) +1 )); //6
printf("%d\n", *(*(q + 1) + 1)); //6 , b[1][1]
printf("%d\n", q[1][1]); //6, b[1][1]
printf("%d\n", **q); //b[0][0]
printf("%d\n", *(*(q+3) - 6)); //7
}
更难一点
int main(void)
{
char c[2][3][4] = {1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,6};
char (*m)[3][4] = c;
printf("%d\n", *(*(m +1)+ 1)); //6
return 0;
}
m——》 1 1 1 1
2 2 2 2
3 3 3 3
m+1—》 4 4 4 4
5 6 0 0
0 0 0 0
指向二维
*(m+1)——》4 4 4 4
*(m+1)+1—》5 6 0 0
0 0 0 0
指向一维
*(*(m+1) + 1)+ 1 == &c[1][1][1]