1、指针数组
char *p[4] = {“zhang”, “li”, “wang”, “chen”};
printf(“常用的姓氏有:[%s] [%s] [%s] [%s]\n”, p[0], p[1], p[2], p[3]);
总结:
①根据C语言的运算符优先级排列顺序,下标运算符[]高于指针运算符*,所以p是跟[]组合,因而得出变量p
是一个数组,而且每个数组元素存放的数据类型是char *,也就是char型数据的地址。
②上面所定义的数组:p[0]存放的是"zhang"的地址,p[1]存放的是"li"的地址,p[2]存放的是"wang"的地址,
p[3]存放的是"chen"的地址。
③指针数组一般用来存放多个字符串常量的首地址,其它的应用不常见。
2、数组指针
int (*p)[4];
int a[3][4] = {{3, 5, 7, 9}, {13, 15, 17, 19}, {23, 25, 27, 29}};
p = &a[0]; //p = a;
printf(“a[1][2] = %d\n”, ((p + 1) + 2)); //输出结果得到17
总结:
①上面定义的变量p是在括号内,先跟*结合,因此得出p是一个指针变量,这个指针变量有点特别,它指向的
是一个拥有4个元素的一维数组,即指向的是数组整体,而不是某个元素。
②第三行代码的赋值语句是把a[0][4]这个一维数组的地址赋值给p,注意这里是整个数组的首地址,而不是数
组元素的首地址。
③数组指针一般用来指向多维数组,平常也是用得不多。
④区分指针数组和数组指针的方法是:看变量名是跟谁走得比较近,先跟[]结合则是指针数组;跟*结合则是
数组指针。
3、指针和一维数组
int a[5] = {6,7,8,9,4};
int *p;
p = a;
p = &a[0];//这两行赋值语句效果一样
总结:
① a代表首个数组元素的地址,也是整个数组的起始地址(需要注意:a不是变量)。
② p是一个指向int型数据的指针变量,在这里它指向数组元素的地址。
③ p+1 和 a+1 都表示a[1]的地址,*(p+1)、*(a+1) 和 a[1]的值一样。
④ p+i 或者 a+i 都表示下标为i的数组元素的地址。
4、指针和二维数组
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *p;
p = a[0];
p = &a[0][0]; //这两行赋值语句效果一样
总结:
① 二维数组a,也可以看做是由3个一维数组组成(如下图),每个一维数组拥有4个元素,所以a[0]相当于
a[0][4]这个一维数组的数组名,a[0]是首个元素的地址。
② 由于a[0]是一维数组a[0][4]的数组名,所以a[0]实际上是等价于&a[0][0]。用行列来描述的话,二维数
组a有3行4列。假设用i表示行、j表示列,则a[i]表示第i行数组的首地址,a[i][j]表示第i行中第j列的元素。
③ *(a+i)+j表示第i行第j列元素的地址,注意这里只是元素的地址不是值。*(*(a+i)+j) 才是获取第i行第j列
元素的值例如*(*(a+2)+1) 的值是10。
本文参考:《C语言程序设计(第四版)》 - 谭浩强