C语言 指针数组和指向指针的指针
针对自己在学习指针知识的时候比较难理解,特意整理出来,防止后面忘了,也拿出来供大家理解
指针数组的概念:
一个数组的元素值为指针则是指针数组。 指针数组是一组有序的指针的集合。 指针数
组的所有元素都必须是具有相同存储类型和指向相同数据类型的指针变量。
指针数组说明的一般形式为:
类型说明符 *数组名[数组长度]
其中类型说明符为指针值所指向的变量的类型
指针数组类型表示的是多个指针(一组有序指针)在一般形式中"*指针数组名"两边不能有
括号。
例如:
int *pa[3]
表示 pa 是一个指针数组,它有三个数组元素,每个元素值都是一个指针,指向整型变量。因为[]的优先级高于*运算符,所以pa[3]表示一个数组,而int*是一个指针定义,则表示pa[3]表示的是一个数组指针变量,数组里面存放的是Int类型的指针,指向int类型数据的地址。
int main(){int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};int *p[3]={a[0],a[1], a[2]};int i=0;//p={a[0],a[1], a[2], a[3]};printf("%d\n",*(*(p + 1) + 3));return 0;}
应该注意指针数组和二维数组指针变量的区别。这两者虽然都可用来表示二维数组,但
是其表示方法和意义是不同的。
二维数组指针变量是单个的变量,其一般形式中"(*指针变量名)"两边的括号不可少。
如:int (*p)[3];
表示一个指向二维数组的指针变量。该二维数组的列数为 3 或分解为一维数组的长度为
3。(*p)先结合成指针类型,然后与数组结合,定义数组里面的数据类型是int型,表示指针p是指向数组里面int的数据
int main(){int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};int (*p)[4];int i=0;p=a;printf("%d\n",(*p)[11]);printf("%d\n",p[1][2]);return 0;}
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量为指向指针的
指针变量。
通过指针访问变量称为间接访问。由于指针变量直接指向变量,所
以称为“单级间址”。而如果通过指向指针的指针变量来访问变量则构成“二级间址”。

定义一个指向指针型数据的指针变量:char **p;
p 前面有两个*号,相当于*(*p)。显然*p 是指针变量的定义形式,如果没有最前面的*,那就
是定义了一个指向字符数据的指针变量。现在它前面又有一个*号,表示指针变量 p 是指向
一个字符指针型变量的。*p 就是 p 所指向的另一个指针变量。
main(){char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer desighn"};//指针数组char **p;//定义指向指针的指针int i;for(i=0;i<5;i++){p=name+i;//一个指向指针的指针指向指针数组的地址printf("%s\n",*p);//读取指向指针的指针指定的地址上面的值}}
p 是指向指针的指针变量。
main(){static int a[5]={1,3,5,7,9};int *num[5]={&a[0],&a[1],&a[2],&a[3],&a[4]};//指针数组存放数组a内容的地址int **p,i;p=num;//数组a的地址存放在指向指针的指针变量p的地址上for(i=0;i<5;i++){printf("%d\t",**p);p++;}//**p要双重解引用,才能读取最上面的值}
指针数组的元素只能存放地址。
对于什么时候用**p,什么时候用*p,就是当指针数组里面的元素存放地址的时候,就使用**p,当指针数组里面的元素是字符串等一些值的时候,就使用*p

