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

C备忘录~1

在C中,用“int a [3]={11,22,33}”可以定义一个长度是3的int数组并初始化;
"int *p=a"可以定义一个指向变量a的指针;
在C中,数组的名称其实是一个指向数组的指针。
那么是不是可以这样定义int *p [3]={11,22,33}来同样表示定义一个长度是3的int数组并初始化 ?

这是一个非常经典且容易混淆的 C 语言语法陷阱。

简短的回答是:不可以。 这样写不仅意义完全不同,而且会导致编译器报错。

1. 核心区别:数组指针 vs. 指针数组

在 C 语言中,[] 运算符的优先级高于 *。因此,你给出的定义会被解析为:

int *p[3] 是一个指针数组(Array of Pointers),即:一个包含 3 个元素的数组,其中每个元素都是一个指向 int指针

而你原本的 int a[3] 是一个整型数组(Array of Integers),即:一个包含 3 个元素的数组,其中每个元素都是一个整数


2. 为什么 int *p[3] = {11, 22, 33} 会报错?

当你写下这行代码时,编译器会尝试将整数 112233 赋值给数组中的三个指针位置:

  • p[0] = (int *)11;
  • p[1] = (int *)22;
  • p[2] = (int *)33;

这在语法上通常会触发警告或错误,因为你试图把一个整数值当作内存地址来处理。如果你后续尝试访问 *p[0],程序会崩溃,因为它会试图读取内存地址为 11 的地方,而那个地方通常是不允许访问的。

and int *p[3] memory layout]


3. 纠正一个观念:“数组名是指针”

你提到“数组的名称其实是一个指向数组的指针”,这在 C 语言学习中是一个常见的简化理解,但并不完全准确:

  • 本质上:数组名是一个常量符号,代表了一块连续的内存空间。
  • 退化(Decay):只有在表达式中(比如赋值给指针或传参时),数组名才会“退化”为指向其第一个元素的地址
  • 区别
    • sizeof(a) 会返回整个数组的大小($3 \times 4 = 12$ 字节)。
    • sizeof(p) 如果 p 是指针,只会返回指针本身的大小(通常是 4 或 8 字节)。

4. 总结与对比

为了清晰起见,我们可以看下表:

定义方式 类型 内存含义 存储的内容
int a[3] = {11, 22, 33} 整型数组 连续空间存 3 个整数 11, 22, 33
int *p = a 整型指针 一个变量,存地址 a 的起始地址
int *p[3] = {&x, &y, &z} 指针数组 连续空间存 3 个地址 指向其他变量的地址

一句话总结:
如果你想要定义一个数组,必须使用 int p[3];如果你加了 * 变成 int *p[3],你定义的就不再是“存数字的容器”,而是“存地址的容器”了。


在 C 语言中,[] 运算符的优先级高于 *。那是不是修改成int(*p)[3]={11,22,33}就可以了?

这是一个非常敏锐的观察!你发现了 C 语言中括号对优先级的改变作用。

但是,依然不可以。修改成 int (*p)[3] 虽然改变了结合方式,但它变成了一个更复杂的概念:数组指针(Array Pointer)

1. int (*p)[3] 是什么?

这里的 p 不再是一个数组,也不是一个简单的整型指针,而是一个指向包含 3 个 int 的数组的指针

  • 它的本质: 是一个指针(在 64 位系统下占 8 字节)。
  • 它的目标: 必须指向一个“完整的数组”,而不是单个整数。

2. 为什么 int (*p)[3] = {11, 22, 33} 会报错?

这行代码在编译器眼中是极其矛盾的:

  1. 左边:是一个指针,它期待接收一个内存地址
  2. 右边:是一个初始化列表 {11, 22, 33},它代表的是实际的数据

你不能把“实际的数据”直接塞给一个“记录地址的变量”。这就像是你手里有一个专门用来写“仓库地址”的小纸条(指针),你却试图把“三件大货”(数据)直接粘在那张纸条上。

3. 正确的用法:指向已有的数组

如果你想使用 int (*p)[3],你必须先有一个真正的数组,然后把数组的地址给它:

int a[3] = {11, 22, 33};  // 先定义一个真实的数组
int (*p)[3] = &a;         // 让指针 p 指向整个数组 a 的地址

and int (*p)[3] memory structure]

4. 彻底理清这三种声明

为了让你不再混淆,我们把这三种极其相似的写法放在一起对比:

写法 名称 语义口诀 内存占用
int a[3] 数组 “我是 3 个整数” 12 字节
int *p[3] 指针数组 “我是 3 个用来存地址的指针” 24 字节 (64位)
int (*p)[3] 数组指针 “我是一个指针,指向一个包含 3 个整数的数组” 8 字节 (64位)

💡 核心结论

在 C 语言中,没有任何一种指针定义方式可以完全替代数组的初始化。

数组负责分配空间并存储数据,而指针只负责指向空间。如果你不先用 int a[3] 这种形式向系统申请那 12 个字节的内存,你就没有地方可以存放 11, 22, 33 这三个数。

http://www.jsqmd.com/news/660074/

相关文章:

  • 2026年,成都高度近视眼镜品牌哪家强?这份推荐不容错过! - 红客云(官方)
  • 5分钟掌握Unity游戏汉化:XUnity自动翻译器终极指南
  • 3分钟定位Windows热键冲突:Hotkey Detective终极指南 [特殊字符]
  • 算法题(155):线段覆盖
  • 剪映自动化终极指南:用Python脚本批量处理视频的完整教程
  • cv_unet_image-colorization部署教程:阿里魔搭ModelScope模型加载详解
  • Android Studio中文界面终极配置指南:三步实现高效中文开发体验
  • Mermaid Live Editor:解决技术文档图表制作的5个核心痛点
  • React Native Offline 部署指南:如何在不同环境中配置和优化网络检测参数
  • 多功能窗口排列工具开发 万能窗口管理软件
  • mmdetection模型测试实战:用`tools/test.py`一键可视化预测结果并保存到指定文件夹
  • 2026年GPT-5完全指南:从发布到应用,一文讲透
  • 深度解析jest-extended数组匹配器:从toBeArray到toIncludeSameMembers
  • 你的macOS多任务效率神器Topit:2分钟掌握窗口置顶技巧,让工作效率翻倍
  • 鸿蒙中 Canvas画布的操作及状态处理(三)
  • 抖音批量下载终极指南:3步搞定无水印视频与音频提取
  • 别再只会仿真了!手把手教你用74LS192修改555定时器抢答器的倒计时时间
  • OpenCode应用场景:AI编程助手如何帮你重构代码、调试bug
  • 终极指南:3个实战场景掌握AMD Ryzen SMU调试工具
  • Python 中的递归赋值总结
  • NVIDIA Profile Inspector完整指南:解锁200+显卡隐藏设置,免费提升游戏性能
  • LTSF-Linear参数调优技巧:10个关键设置让你的预测精度提升50%
  • SAM 3在电商场景的应用:快速分割商品主体,制作白底图so easy
  • 中文句子相似度判断神器:StructBERT本地部署保姆级教程
  • 抖音/B站/快手/小H书直播录制神器!原画超清无水印+自动监控+分段存储,主播开播秒抓取
  • SpringBoot+Vue二手闲置交易系统源码+论文
  • 2026年3月优质包装机定做厂家推荐,全自动三维包装机/透明膜三维包装机/枕式收缩包装机/封箱打包流水线,包装机品牌推荐 - 品牌推荐师
  • 别再死记硬背了!用Python脚本自动解析3GPP 27.007 AT指令(附源码)
  • 你的口袋渗透实验室:详解NetHunter Rootless在Termux下的工作原理与高级用法
  • 百川2-13B模型IDEA插件开发构思:智能代码审查提示