C语言一维数组名究竟是什么

1.问题

按照我一贯的理解, 一维数组名==首元素地址==常量,理解马马虎虎,日常使用并没有什么问题

直到有一天我在思考一个左值右值的问题时,发现了数组名的不同

问题:既然数组名是常量,我们都知道常量不能当左值,所以我认为int a[5];a=5;和5=5;应该有相同的报错,因为错误原因都相同:常量不能作为左值, 但是实际是这样吗?看看下面的结果, 是不是很困惑, 报错不应该都是赋值运算左操作数必须是左值的问题吗?

root@ubuntu:/lianxi/lianxi_oj/array# gcc array_name.c -m32
array_name.c: 在函数‘main’中:
array_name.c:5:4: 错误: 将‘int’赋值给‘int[5]’时类型不兼容
array_name.c:6:4: 错误: 赋值运算的左操作数必须是左值
root@ubuntu:/lianxi/lianxi_oj/array# 
  1 #include <stdio.h>
  2 int main(void)
  3 {   
  4     int a[5] = {0};
  5     a = 5;//
  6     5 = 5;//
  7     return 0;
  8 }

2. <C和指针>对数组名的阐述

可以看到这里说得比较含糊, 但是能够粗略地看出一个事实:数组名首先是个常量, 在C语言中绝大多数用到数组名的表达式中编译器会把数组名解释为地址常量, 这时类型取决于数组元素的类型

3. 搜索到的博客

我把我搜索到写得好的博客贴在下面:

https://blog.csdn.net/chuhe163/article/details/80795728

https://www.cnblogs.com/liqiuhao/p/7737539.html

http://blog.chinaunix.net/uid-27004869-id-3301282.html

其中第二篇博客引用了C99标准中的话, 我们摘出来看看:

这里我们又可以得出一个结论:在sizeof运算符, 取地址运算符&和本身就表示数组这三种情况下, 数组名表达式具有类型"array of type", 而在其他绝大多数的表达式中数组名表达式会被转化为地址常量

4. 我的理解和结论

结合上面的分析, 我把自己的理解和结论贴在下面, 如不正确, 请指出或者来日我有新理解会回来改正

1).当程序完成链接后, 内存中数组的位置是固定的, 所以整个数组首元素首字节的地址编号也是固定的

2).数组名是个符号, 类似于宏定义中的符号常量, 假如int a[5]数组首元素首字节的地址编号是0x08048000, 那么数组名类似于如下操作:#define a 0x08048000

3).在sizeof,取地址符及本身就表示数组的表达式中, 数组名表达式具有"arrayof type"类型, 例如int[5]类型, 这一点也能解释在本文开头时给数组名赋值报错的原因

4).在除开3)中的场景外, C语言中绝大多数的数组名表达式编译器会将其转化为地址常量, 如上例子, int a[5], &a[0] == 0x08048000, 那么:a[1] <=> *(a + 1) <=> *((int*)(0x08048000) + 1) <=> *((int*)0x08048004), 这有点类似于我们平常习惯的读写寄存器操作

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值