数组名和指针的区别

本文解析了数组名与指针在使用上的细微差别,并通过具体示例说明了为何在某些情况下将数组名当作指针使用会导致运行时错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    我们平常学习的时候用一个指针指向数组名,然后指针就可以和数组也一样通过下标访问了,以至于我们似乎觉得指针和数组没有什么差别。例:
                    int a[10] = {0};
                     int * p = a;
                     p[3] = 6;   //ok 没有问题 不会报错

但是我们再看一个例子:
在A文件中:
int a[10];

int *b = a;

在B文件中:
extern int *a;
extern int b[];
.....

int x,y;

x = a[3];
y = b[3];

    如果我们将两个文件经过编译汇编后链接到一块后,运行时会报错,大家知道为什么吗,如果大家已经想到了出错原因,想必也已经知道数组名和指针的区别了。
    下面我们来分析一下:

     在A文件中编译的时候,我们的a是一个数组名,大家看到数组名一定要切记一句话:
     数组名就是第一个元素的地址,数组名就是地址。
    也许有心的同学会发现当我们对数组名求sizeof的时候它是整个数组所占元素的大小,我们输出
    cout<<a<<&a<<endl;
    是同一个地址,也就是说a这个数组名本身就代表一个是数组的地址,和我们指针是有区别的,我们定义一个指针p =a;

    p这个变量里存放的是a的地址,即数组的首元素地址,但是对p取址是p自己这个变量所占的内存地址,话说了这么多,不如看个图,简洁明了。
我们看看这个图大家应该就明白我们两个赋值语句错在哪里了。

x = a[3];
在我们的B文件中,a是一个指针,也就是说是p这样的结构,它的符号表里应该记录了a本身的地址,而因为是外部符号,所以我们链接的时候会将A文件中定义的数组名即地址0x200赋值给p作为它本身的变量地址,但是指针和数组名处理方式不同,当把它当成一个指针处理的时候,它先找到0x200这个这个地址,认为这是它自己的地址,再从它的空间里面取出值,认为这个内容才是它保存的指向的地址的值,而0x200里的值,想必大家也看出来了,就是a[0],所以它把a[0] 作为指向的地址,把这个值作为一个地址+3*4 = 12 个字节,再取里面的值,这简直就是胡来,这个地址要么是任意地址,要么一不小心就定位到了不可访问的地址,所以运行时会有错误,它发现你非法访问了。我们还是看图再参照上面文字理解一下:

y = b[3];错误的原因也是一样的道理
本来在B文件中定义了一个int b[] 的数组名,但是链接在汇编的时候就已经确定外部符号b的变量地址就作为数组的起始地址来用,还是看图

还是切记一句话:数组名就是首元素地址!!!!!对数组名取址也还是首元素的地址,但是指针就不一样,指针里存储的是数组的首元素地址,但是对指针取址却是它自己的地址,和数组首元素地址不同!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值