int a[2][5] = { {1, 2, 3, 4, 5}, {6, 7, 8, 9, 10} };
int* p4 = a[0]; //a[0]是数组,右值是指向数组第一个元素的常量指针
int* p5 = &a[0][0]; //a[0][0]是1,&取地址。 即P4==P5。
int(*p)[5] = a;//数组名a的本质是指向数组的指针。 区别 int *p[5],这是指针数组,指针为指向int的指针。
int** b = (int**)a;//强转,将指向数组的指针转为指向指针(该指针指向int)的指针
int foo(int** b)
{
return b[1][3];
}
int main()
{
printf("% p \ n ", a);//a的右值就是P4,P5。
printf("% p \ n ", a+1);//但是a+1中,1代表数组的大小
printf("% p \ n ", p4);
printf("% p \ n ", b);//b是指向指针(该指针指向int)的指针,值也为P4
printf("% p \ n ", b+1);//int4B,指向int的指针4B,+1代表指向int的指针的大小4B
printf("% p \ n ", *b);//*b是指向int的指针,此处b的右值为P4,*b的右值为1
printf("% d \ n ", **b);//**b是该int,即地址0001处的值。
//printf("% d \ n ", foo(b));
return 0;
}
> a:函数名的右值00D6C000,类型是int(*p)[5],指向数组的指针。
> a+1:根据数组大小,int为4B,数组大小为5,4B×5=20B,则a+1的右值为00D6C000+00000014(20的16进制)。
> p4:二维数组第一行的第一个元素的地址。00D6C000 b:将a强制转换为二重指针(int **),右值等于a的右值。00D6C000
> b+1:b是指向指针(该指针指向int)的指针,因为指向int的指针大小为4B,b+1的右值为00D6C000+4
> *b:间接访问b的右值00D6C000,也就是第一个元素1,*b=1.
> **b:间接访问*b的右值00000001,和数组八竿子打不着了。
难点:
A.a+1和b+1的地址不再相同,因为a是指向数组的指针,+1实际上是数组的大小20B;而b是普通的指向指针的指针,大小为4B。
B.a+1的地址和*a+1的地址也不相同。因为*a是第一个数组,也就是*a是指向数组第一个元素的指针,*该元素为int类型,4B.
回顾:
*(*(a+1)+3)的值是第二个数组的第三个元素,a[1][4]
*(*(b+1)+3)的值是地址为14的元素的值。因为*(b+1)的右值是2,类型为指向int的指针,
int大小4B,则*(b+1)+3的右值为14,间接访问14,即*(*(b+1)+3),该值未知。