C语言,二维数组,二重指针,数组名和指针之间的关系

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:根据数组大小,int4B,数组大小为545=20B,则a+1的右值为00D6C000+00000014(2016进制)> 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),该值未知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值