有关a和&a[0]的问题

有关a和&a[0]的问题

在课程中,老师说a和&a等价,这点我可以理解,并且通过代码可以验证

https://img1.sycdn.imooc.com//climg/64bc74870991368803100179.jpg

https://img1.sycdn.imooc.com//climg/64bc745a0981bfd610800130.jpg

通过编译器警告,可以看到a和&a[0]都是int *类型。但是老师在后面说a是一个int [5]类型的数组

https://img1.sycdn.imooc.com//climg/64bc74ff09215c1603450164.jpg

在这里有些不理解,为什么a的类型变成了int [5]?

正在回答

登陆购买课程后可参与讨论,去登陆

2回答
可以粗略这样理解吧!因为数组是一个比较特殊的东西!可以从一维数组来理解!
int a[5] ; 

int *p = a;
int. *p = &a[0];
因为这里其实有个编译器转化的,p本质保存的是a[0]的地址!
int (*p)[5] = &a;
理解了一维,二维是一样的!
int a[3][2] ;
int *p[2] = a;这里本质也是保存a[0]的地址
大白老师 2023-07-23 10:26:47
首先明确一个规定,属于名代表数组首元素的地址!
int a[5];
a<==>&a[0]
注意这里的等价只是说的数值上的等价,并没有说类型等价!
换句话说假设a[0]的地址是0x9000,那么a的值也是0x9000。这里只是值相等!但是类型不是这么看的!

类型的确定:把变量名去掉后剩下的就是类型。
int a[5];变量a去掉后就是int [5]。
还有种理解,a的类型是整个数组,5个int
要不怎么理解,sizeof(a)输出是20byte,整个数组的大小!

在教你一种简单的验证方式.代码中输出下面的话!标准器会有警告提示具体类型。
printf("a = %#x\n",a);
printf("&a[0] = %#x\n",&a[0]);
  • 提问者 万能小企鹅 #1

    老师,我按照你的代码作了输出,结果是两个都为int *类型

    https://img1.sycdn.imooc.com//climg/64bcb77a09b71fcf03660181.jpg

    https://img1.sycdn.imooc.com//climg/64bcb6dc094dbcb907210306.jpg

    但是如果对比的是a和&a,&a的结果是int (*)[5],从我的理解来看,a完全等价于&a[0],是int *类型,其储存的值也是相同的,都是数组首个元素的内存地址;而&a是一个数组指针,类型为int (*)[5],虽然值还是首元素的地址,但是变量类型是一个数组指针,此种情况下&a+1移动的是一个数组的长度。

    https://img1.sycdn.imooc.com//climg/64bcb95709ceb0fe07250289.jpg

    这个对我来说很困惑,还请老师再帮忙解答。

    2023-07-23 13:28:51
  • 大白老师 回复 提问者 万能小企鹅 #2

    这里估计是新版的编译器优化了,我记得以前老版本的编译器可以看的。我在教你一个通过gdb调试的方法查看变量的类型。
    使用方法:
    gcc -g  test.c      //输出a.out添加调试信息
    gdb a.out           //进入gdb调试信息。
    start                   //开始调试
    s                        //单步执行
    ptype  a            // 输出数组a的类型
    ptype  a[0]        // 输出a[0]的类型

    https://img1.sycdn.imooc.com//climg/64bd2ecd09ef3c8610180765.jpghttps://img1.sycdn.imooc.com//climg/64bd2d8c09bdb31107580504.jpg

    2023-07-23 21:47:10
  • 提问者 万能小企鹅 回复 大白老师 #3

    老师,这个用gbd调试的方法很好用,解决了很多疑问。我还有一个疑问,我写了下面这段代码:

    #include <stdio.h>
    
    int main()
    {
        int a[3][2] = {{1,2},{3,4},{5,6}};
        int (*p)[2] = a;
    
        printf("%#x\n", a);
        printf("%#x\n", &a);
        printf("%#x\n", &a[0]);
        printf("%#x\n", &a[0][0]);
        return 0;
    }

    输出的结果是

    0x9ffdf0
    0x9ffdf0
    0x9ffdf0
    0x9ffdf0

    通过gdb调试可以看到这些变量的类型

    https://img1.sycdn.imooc.com//climg/64bd4de3092f1e9b02090155.jpg

    在int (*p)[2] = a;这一步时,实际上是将int [3][2]类型的变量a赋值给了p,此时编译器未提示任何信息。是否可以理解为编译器自动将int [3][2]类型的a,转换成了int *[2]的&a[0]这个数组指针,并赋值给了p?这个值同时也是二维数组中元素a[0][0]的地址?

    2023-07-24 00:05:25
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师