#include<stdio.h>
int main(){
int array[4][3] = {{1,2,3},{4,5,6},{7,8,9},{10,11,12}};
int (*p)[3] = NULL;
p = array; // p is same as array,the use of p is same as array.
//so p is the two-devision pointer same as array
int *p1 = &array[0][0]; //p1 is the one-devision pointer
int *p2 = array[0];
//int **p3 = array; this is wrong. the array's kind is int(*)[3]
//but p3 is int**
printf("%d ",*array[0]);//out:1
//(*p)[n] think array is the one-devsion array
//so (*p) is the header pointer of the one-devision array
//so (*p)[1],(*p)[2]......(*p)[i] is right
printf("%d ",(*p)[0]);//out:1
printf("%d ",(*p)[1]);//out:2
printf("%d ",(*p)[2]);//out:3
printf("(*p)[3]:%d ",(*p)[3]);//out:4
printf("(*p)[4]:%d ",(*p)[4]);//out:5
printf("(*p)[5]:%d ",(*p)[5]);//out:6
//think p is same totaly as array
//*p pointing the zero row
//*(p+1) pointing the one row
//*(p+2) pointing the two row
//*(p+3) pointing the three row
//and array is four rows, so *(p+4) is overflow
printf("%d ",(*(p+1))[0]); //out:4
printf("%d ",(*(p+2))[0]); //out:7
printf("%d ",*(p+3)[0]); //out:10
printf("%d ",*(p+3)[1]); //overflow
printf("%d ",(*(p+3))[1]); //11
printf("%d ",(*(array+3))[1]);//11
printf("%d ",*(array+3)[1]);//overflow
printf("*(array+3)[0]: %d ",*(array+3)[0]); //10
printf("*(array+3)[1]: %d \n ",*(array+3)[1]); //overflow
printf("%d \n",*(*(p+3)+1)); //out:11
printf("*(array[3*3+1]):%d \n",*(array[3*3+1])); //overflow
printf("*array[3*3+1]:%d \n",*array[3*3+1]); //overflow
//printf("*array[3*3+1]:%d ",**array[3*3+1]); // is wrong **array[3*3+1]
printf("%d \n",*p[3*3+1]); //overflow
printf("*(array[3]+1):%d \n",*(array[3]+1)); //11
printf("%d \n ",*(p+4)[0]); //overflow
/*all below is wrong. p1 is the pointer pointing array[0][0]
* pi++ pointing array[0][1] and so on .the adder is sizeof(int)
*
printf("%d ",(*p1)[0]);//out:1
printf("%d ",(*p1)[1]);//out:2
printf("%d ",(*p1)[2]);//out:3
printf("(*p1)[3]:%d ",(*p1)[3]);//out:4
printf("(*p1)[4]:%d ",(*p1)[4]);//out:5
printf("(*p1)[5]:%d ",(*p1)[5]);//out:6
printf("%d ",*(p1+1)[0]); //out:4
printf("%d ",*(p1+2)[0]); //out:7
printf("%d ",*(p1+3)[0]); //out:10
*/
int i = 0;
for(i;i<12;i++){
printf("%d ",*(p1+i));
}
printf("\n");
// for p2=array[0]
printf("%d ",*p2);//1
printf("%d ",*p2+10); //11
printf("%d ",*(p2+1));//2
printf("%d ",*(p2+2));//3
printf("%d ",*(p2+3));//4
printf("%d ",*(p2+4));//5
printf("%d ",*(p2+5));//6
printf("%d ",*(p2+6));//7
printf("%d ", *p2++); //1
printf("%d ",*p2);
}
对于二维数组用指针只能是上述p和p1和p2的用法,p3的赋值方法是错误的。
访问二维数组array[i][j]的方法有3种:*(array[i]+j) array[i][j] *(*(array+i)+j)
当int (*p)[3]=array时,p和array是一样的,都是行指针,则在行指针进行加法运算时,是行间的移动,例如array+i 和p+i,是跨行的移动
int *p1=&array[0][0] 此时p1是一维指针,则现在将二维数组看作一个一维数组,然后p1的移位操作来进行逐个元素进行访问。
p2同p1
还要注意的是:int *a[3] 说明的先后顺序是:p-->[3]-->*-->int 先说明数组,再说明指针;这是一个指针数组(指针数组,数组存储的是指针,将在下一篇文章中讲解)
所以上面代码中,如下:
printf("%d ",*(p+3)[1]); //overflow
printf("%d ",(*(p+3))[1]); //11
printf("%d ",(*(array+3))[1]);//11
printf("%d ",*(array+3)[1]);//overflow
要用(*(array+3))[1])这样的形式,用括号将*运算括起来先进行运算,(*(array+3)):表示{10,11,12}这个数组的首地址,再用[]操作来根据脚标进行取值。
printf("*array[3*3+1]:%d \n",*array[3*3+1]); //overflow
这样的访问是错误的,因为array是行指针,所以array[3*3+1]已经越界了