当前位置: 首页 > news >正文

数组名的隐式转换规则

在C语言中数组名在绝大多数表达式场景中,会自动转换成指向数组首元素的指针

1.1触发条件

当数组名作为表达式使用时,除两种情况外,都会发生该隐式转换

1.2触发结果

数组名会转化为指向数组首元素的指针,指针的类型由数组元素的类型决定


例外
1.数组名作为sizeof的操作数
2.数组名作为&的操作数


为了便于加深其重要性的理解,我下面举几个例子
下面我用退化代替隐式转换

//这里以32位系统,int占4字节为前提 #include<stdio.h> int main() { int arr[5] = { 0 }; printf("%zu\n",sizeof(arr)); //此时输出的结果为20,数组名作为sizeof的操作数,未发生退化,视为整个数组 printf("%zu\n",sizeof(arr + 1)); //此时输出的结果为4,数组名先与+结合,发生隐式转换视为数组首元素的指针int*,再加一,为指向arr[1]的指针,又是32位系统,所以是4 printf("%zu\n",sizeof(*arr)); //结果为4,arr先与*结合,发生退化,对首元素地址解引用得到首元素,int型,所以结果是4 printf("%zu\n",sizeof(&arr + 1)); //结果为4,arr先与&结合,取出整个数组的地址,类型为数组指针int(*)[5],再加一还是数组指针,相当于跳过了一个含有五个int类型的数组,指针在32位系统下占4个byte return 0; } 我们再来看几个例子 #include<stdio.h> int main() { int arr[3][5] = { 0 }; printf("%zu\n",sizeof(arr)); //未发生退化,是整个二位数组,类型int[3][5],结果为60 printf("%zu\n",sizeof(arr[0][0])); //表示第一个二维数组首元素,int类型,所以结果为4 printf("%zu\n",sizeof(arr[0])); //可视为*(arr + 0),发生退化(当然不这么看也可以,可以理解为下标引用结合后直接是二维数组的首个一维数组的数组名,但这个假想的数组其实没名字,也就是第0行) //arr代表二维数组的第一个元素也就是所谓的第一行的数组int[5]的指针(这和下标引用操作符有关),再+0不变,解引用后就变为了第一行的数组,所以结果为20 //本质上就是表示二维数组的第一个元素,也就是第一行,所以结果为20 printf("%zu\n",sizeof(arr[0] + 1)); //参与表达式运算,arr[0]可以看作计算出了int[5],(不过这个子数组没名字,我就写成这种形式了,上面的例子也是一个道理),参与计算发生衰退,变为指向首元素的指针int* //加一相当于指向了第二个元素(下标是1)的指针,所以结果为4 //第一行参与运算,退化,变为指向第一行的数组指针,加一,变为指向第二行,指针,所以结果为4 printf("%zu\n",sizeof(arr + 1)); //数组名参与表达式运算,发生退化,变为指向首元素的指针int(*)[5],就是第一行(下标为零)加一是第二行,但是是指针,所以结果为4 printf("%zu\n",sizeof(*(arr + 1))); //对第二行的数组指针解引用,得到第二行,结果为20 printf("%zu\n",sizeof(&arr[0] + 1)); //取出第一行的地址,是一个数组指针,加一变为指向第二行的数组指针,结果为4 printf("%zu\n",sizeof(*(&arr[0] + 1))); //对指向第二行的数组指针解引用,得到第二行,结果为20 printf("%zu\n",sizeof(*arr)); //数组名与*结合,退化为首元素的指针,也就是指向第一行的数组指针,解引用得到第一行,结果为20 printf("%zu\n",sizeof(arr[4])); //虽然越界了,但sizeof只看类型,不进行实际的运行,所以结果为20 return 0; }
http://www.jsqmd.com/news/1099682/

相关文章:

  • 2026 照片恢复教程|5 种零基础恢复技巧汇总,最后一个90%人不知道!
  • FPGA加速数字孪生:GRU算法与硬件优化实践
  • 【Springboot毕设全套源码+文档】基于Java+springboot电缆行业生产管理系统的设计与实现(丰富项目+远程调试+讲解+定制)
  • 自动灌溉系统:AI 什么时候浇水,比老农还准?
  • 为什么我们需要关注线程?
  • 解密高并发视频中台:基于 Docker 容器化与 GB28181/RTSP 协议栈的边缘计算全纳架构(附源码交付)
  • tqdm进度条:让命令行程序更友好
  • SkyWalking:分布式系统的全栈监控方案
  • PTA 7-4 列车调度题解:不用队列,一个数组搞定(C语言版,含时间复杂度分析)
  • Linux的职业(要求)与虚拟机安装教程
  • MFile:不止是Minio的“管理中介”
  • Keil MDK vs ARM-GCC(arm-none-eabi-gcc)完整区别
  • Fuso:一个内网穿透工具,用 Rust 写的
  • 战略落地,只差这一步
  • 从手动到半自动:CSDN 技术博客发布效率提升实践(验证版)
  • 关于ISACA第五届数字信任大会两大权威文件
  • “Memory in the Age of AI Agents: A Survey“ 论文笔记
  • 2026年AI写长篇小说工具终极测评:5款热门工具横评,长篇选手到底选哪个
  • define和typedef的区别详解
  • 批量处理远程共享目录中的特定类型文件(如 .hex、.csv 等)。
  • 关于 Vaadin:专为企业级应用打造的 Java Web UI 框架
  • 8元现金优惠券,无门槛直接使用
  • 剪映专业版教程:制作照片旋转轮播效果
  • 专访零数科技林乐:他为何坚信“数据利用”比“数据流通”更接近数字经济的本质?
  • 北斗赋能海洋精准定位
  • 开源WPS AI插件察元AI文档助手:updateTask 与终结状态的时间戳
  • 纳米级重复精度国产三维轮廓仪性价比之选
  • 【JAVA毕设源码分享】基于springboot大学生社交平台的设计与实现(程序+文档+代码讲解+一条龙定制)
  • 快速部署:三步搞定前后端启动
  • 2.3 内核层:时钟信号与硬件保护电路