int **p;这是指向指针的指针,表示指针变量p应指向一个指针的地址,注意一定要是指针的地址才不会出错,比如
int a=1; int *p1=&a; int **p=&p1;不能是int **p=&a;因为变量a不是指针,同理
对二维数组a[2][3]的数组名
这里要注意,这里的数组名并不是一个简单的指针,二维数组的数组名是一个指向一维数组的指针,也就是数组名a是一个指向包含有三个元素的一维数组的指针,即(*)[3];因此不可以把数组名赋给指向指针的指针**p,应该把二维数组名赋给int (*p)[3]这样的指针,这样的指针表示的就是一个指向包含有3个元素的一个数组的指针。
对于数组名不是一个简单的问题,比如一维数组名a[3]那么数组名a表示的是指向第一个元素的指针,但&a却表示的是指向一个含有3个元素的一维数组的指针,具体问题的研究,请去本人的文库下载相应文章吧
简单给你解释下
p是数组,每一个数组元素都是指针,因此*p[1]表示的是指针p[1]所指向地址的值,而p[1]表示的是指针p[1]所指向的地址,因此*p[1]和p[1]是不相同的。现在我们来看数组名p,数组名p表示的地址是&p[0],也就是指针p[0]的地址。
要记住无论是多少维的数组,他的数组名都表示的是&a[0]的地址。
具体的内容请下载本人文章《C指针与数组的混合运算》里面有讲解
int a[2][3]; a的类型相当于 int (*)[3]而不是int **
int a[2][3];
int (*b)[3] = a; 这是可以的
---
int *p[3];
数组类型变量参与运算的时候视为指针。运算时的p[0],这里[]是指针的运算符,数组类型不会直接参与运算。 p[0]就是 *(p + 0) 也就是*p 显然p可以看成int **类型的
---
只有运算的时候 int *[]才是int **,声明的时候int *p[3]和int **p是不一样的。int **p是一个指针的空间,里面存的数据是int **,int *q[3]是3个指针空间里面存的数据是int *。
p用的时候是直接使用它保存的数据,q在用的时候使用的是声明的变量的首地址,因为那个地址保存的数据是int *所以地址的类型也就是int **。
p: |(int **)|
q: |(int *)|(int *)|(int *)|
数组在运算时候转意为指针,但是数组变量本身不等于指针。p你可以用int **赋值,但是q不可以,因为q转意得到的int **并不是保存在变量里的。
int *p[2];
int *q[3];
int **z;
p = q;// 错误
盯住这个错误不放,应该能够理解你所说的问题
那个 z ,就更没谱了 ^_^