C语言中数组名a、数组名取地址&a、数组首元素地址&a[0]三者的概念有点绕,花了点时间好好琢磨了一下,将自己的理解记录下来,如有错误之处,欢迎赐教。
首先看下面的一小段代码:

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

数组名 a 是一个常量指针,指向数组的起始地址;数组首元素的地址 &a[0] 指向数组第一个元素的地址,也就是数组的起始地址,这两点大部分人应该都是知道的。但是对数组名 a 取地址会得到什么结果?这点估计不少人没有仔细想过。上述代码的执行结果如下(WIN32环境):

a       = 00DEF97C
&a[0]   = 00DEF97C
&a      = 00DEF97C
a+1     = 00DEF980
&a[0]+1 = 00DEF980
&a+1    = 00DEF988

&a 表示的地址与前两个地址一样,但 &a+1 表示的地址与前两个却不一样!这说明 &a 的指针类型与 a 的指针类型不一样,a+1 的地址相对于 a 的地址偏移了4个字节,很显然因为 a 是 int 类型的指针;而 &a+1 的地址相对于 &a 的地址偏移了12个字节,这正好是 int a[3] 数组所占内存空间的大小,所以 &a
实际上是一个数组指针,形如 int (*p)[3],指向具有3个元素的数组。

以下是我画的数组a在内存中的存储示意图(32位平台,小端模式),辅助理解。

如上图左侧所示,a 指向地址 0x00DEF97C,那么 a+1 就指向了 0x00DEF980,步进了1个int类型数据的地址空间。
如上图右侧所示,&a 指向地址 0x00DEF97C,那么 &a+1 就指向了 0x00DEF988,步进了1个int a[3]数组的地址空间。

指针能表示两个维度的信息,第一个是内存当中的地址,第二个是访问内存的“尺度”。
数组名 a、数组首元素的地址 &a[0]、数组名取地址 &a,这三者在内存中其实是同一个地址,但访问内存的尺度有所不同,其中 a 和 &a[0] 是以 int 类型所占内存空间为尺度来访问内存,而 &a 是以数组 int a[3] 所占内存空间为尺度来访问内存。

打个比方,假设内存是一栋教学楼,数组 a 是其中第一层,共有 3 个教室,那么 a[0] 是一年级一班,a[1] 是一年级二班,a[2] 是一年级三班,这时候一年级一班的门顶上可能就是下面这样的门牌号:

F1表示这是一楼,等价于数组名取地址 &a
一年级等价于数组名 a
101表示这是一楼第一个房间(一年级一班),等价于数组首元素地址&a[0]

有了上面的类比,接下来就好理解了:

&a 是按楼层访问(也就是按年级访问),&a+1 就指向二楼F2(二年级)
a 有点特殊,
作为变量它表示的是一年级,sizeof(a) 得到的是一年级的班级数量 * 单个班级所占的空间;
作为地址它等价于首元素地址(一年级一班的地址),是按班级访问,a+1 就指向一年级二班
&a[0] 是按班级访问,&a[0]+1 自然指向的就是一年级二班

C语言数组名、数组名取地址、数组首元素地址之间的关系相关推荐

  1. 【C 语言】数组 ( 数组相关地址 | 数组首元素地址 | 数组地址 )

    文章目录 一.数组相关地址 1.数组首元素地址 2.数组地址 二.代码示例 一.数组相关地址 数组首元素地址 与 数组地址 值相等 ; int array[10]; 其中 array + 1 的值是 ...

  2. 【C 语言】数据类型本质 ( 数据类型 | 数据类型本质 | 数组地址 | 数组首元素地址 )

    文章目录 一.数据类型 二.数据类型本质 ( 数组地址 | 数组首元素地址 ) 一.数据类型 " 数据类型 " 是 数据的抽象 ; 相同类型的数据 , 表示形式相同 , 存储格式相 ...

  3. 511遇见易语言API模块视频教程进程取ID数组

    本课是完成大漠多线程的必须写封装的命令,因为线程我们要同时获取多个窗口的句柄,那么我们可以先获取多个窗口的进程ID数组,再根据进程ID分别获取窗口句柄. 视频链接 511遇见易语言模块API教程 思路 ...

  4. arr和arr的区别以及数组首元素地址和整个数组地址的区别

    1.arr和&arr 我们学过C语言可以知道,arr并不是C语言中的关键字,只是普通的用户定义标识符.是取array(数组)前三个字符来定义数组. 不管你用arr[]={0}还是a[]={0} ...

  5. 网址(url),域名,ip地址,dns,hosts之间的关系

    网址(url),域名,ip地址,dns,hosts之间的关系 什么是ip? 我们知道,在Internet上有千百万台主机,为了区分这些主机,人们给每台主机都分配了一个专门的地址,称为IP地址.通过IP ...

  6. 学校(School)主要有3大角色:学校(School),讲师(Teacher),学员(Student)。请用Python语言简要实现这些类及及其属性,以及它们之间的关系。

    学校(School)主要有3大角色:学校(School),讲师(Teacher),学员(Student). 学校可以注册学员,统计有多少学员 讲师负责讲课 学生听课,提问,学习,交学费 Teacher ...

  7. 数组名不代表首元素地址的两种例外情况

    目录 1.例外一:&数组名 2.例外二:sizeof (arr) 通常情况下,数组名表示的是数组首元素的地址.此时我们可以使用一个指针变量来接收这个地址 int arr[10] = {1 , ...

  8. C语言(较深入原理):%s通过字符串首元素地址输出,用指针数组来作示例

    首先,我们输出一个字符串都知道是用%s来输出,但是我们并没有多想是通过什么方式来输出的. 今天我在看指针数组的时候发现了一个问题,按就是定义一个字符类型的指针数组, /*字符串的输出本身就需要他的地址 ...

  9. IP地址(A、B、C、D和E类)、网络地址、主机地址、子网掩码与网关之间的关系

    "IP地址"就相当于"电话号码",而Internet中的路由器,就相当于电信局的"程控式交换机". 点分十进制数表示的IPv4地址被分为几类 ...

最新文章

  1. Java 14 :NullPointerException的处理新方式
  2. 游戏外挂的基本编写原理
  3. 安装fastdfs出现/usr/local/lib/libfastcommon.so: undefined reference to `fcntl64@GLIBC_2.28‘
  4. 汇编中call printf参数压栈时错误理解
  5. inline,block,inline-block的区别
  6. 一波情人节海报温暖来袭,注定与众不同
  7. Exploit 代码用于攻击中?GitHub 马上删除
  8. Android UsageStatsService(应用使用统计服务)的学习与调研
  9. ABAQUS2018汉化
  10. hping 详解_hping3命令
  11. xjad反编译遇到break MISSING_BLOCK_LABEL_365问题
  12. mysql如何源码安装_超详细的MySQL源码编译安装与配置 值得收藏!
  13. java.lang.IllegalStateException: Found multiple @SpringBootConfiguration annotated classes
  14. 90%的 CTO 都做不好绩效管理
  15. java备忘--20190828
  16. 微信开放平台开发 微信登录
  17. 劳动保障职业学院计算机专业,北京劳动保障职业学院2020录取分数线(附2017-2020年分数线)...
  18. HTML day_02(6.1)表格列表、结构标记 、 表单、新表单元素
  19. 傲慢与偏见之 - 谷歌中国逆袭史
  20. Matlab GUI handles结构体入门

热门文章

  1. 股票交易接口开发原理是什么?
  2. 懒人数据库 MongoDB 5.x
  3. Unity3D和UE4游戏开发引擎哪个是游戏开发者最爱?
  4. Three.js + React + Echart(折线图 光线流动效果,柱状图数据动态更新动画) + Svga-Web应用之数据大屏(适配1920*1080 2560*1440 3840*2160)
  5. 云图科技,长沙VR全景打造旅游业新视角
  6. java获取GET和POST请求参数
  7. flutter项目模板
  8. C语言的函数讲解(一)
  9. # java swing,awt图形化界面代码案例合集
  10. element 解决 Error: target is not existed: .page-component__scroll .el-scrollbar__wrap