首先 指针式分级别的 *p是一级指针 **p是二级指针
比如我们定义
int a[5];
int *p;
此时 a作为数组中第一个元素的地址 是一个一级 指针, 所以 直接 p=a 就可以
若要得到第n个元素 只需 *(p+n)
下面主要讨论二维数组与指针
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
int *p;
int (*p)[3];
数组a是一个二维数组,其在内存中的存储方式 是顺序存储的,如果我们用p访问任意一个元素的话 有如下方法 比如访问a[2][2];
1.p=&[0][0]; *(p+2*3+2);
2.p=a[0]; *(p+2*3+2);
但是不能使用 p=a;
首先对于上面的二维数组a 可以看做 数组a有三个元素{a[0],a[1],a[2]}; 其中每个元素为一个包含3个值的数组, 所以 a其实是a[0]的地址,a+1 是a[1]的地址
这样*a 就得到了a[0]的内容 而a[0]是一个有三个元素的数组{1,2,3} 的首元素的地址,所以再*a[0] 才得到1; 从这个过程来看 a是一个二级指针,显然不能直接赋值给p
*a与a[0]等价、*(a+1)与a[1]等价、*(a+2)与a[2]等价
由此,对于数组元素a[i][j],用数组名a的表示形式为:
*(*(a+i)+j)
指向该元素的指针为:
*(a+i)+j
对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同,a[0]是一维数组的名字,它指向的是a[0]数组的首元素,对其进行“*”运算,得到的是一个数组元素值,即a[0]数组首元素值,因此,*a[0]与a[0][0]是同一个值;
而a是一个二维数组的名字,它指向的是它所属元素的首元素,它的每一个元素都是一个行数组,因此,它的指针移动单位是“行”,所以a+i指向的是第i个行数组,即指向a[i]。对a进行“*”运算,得到的是一维数组a[0]的首地址,即*a与a[0]是同一个值。当用int *p;定义指针p时,p的指向是一个int型数据,而不是一个地址,因此,用a[0]对p赋值是正确的,而用a对p赋值是错误的。这一点请读者务必注意。