章节名称 — 目录

← 返回 MOC | ← 主页


1. 场景一:作为函数参数(它们是等价的)

书里开头提到,在函数的参数列表里,char s[]char *s 完全是一回事

  • 为什么? 因为 C 语言为了效率,不会在你调用函数时把整个数组“复印”一份传进去。
  • 真相: 无论你写成数组形式还是指针形式,编译器都会偷偷把数组名转换成指向首元素的 指针 。所以,你在函数里改 s[0],改的就是外面的原件。

2. 场景二:extern 声明(这是最危险的陷阱!)

这是书里强调的“天渊之别”。如果你在 A 文件定义了一个数组,在 B 文件想引用它,声明方式错一点程序就会崩。

声明方式含义就像是…
extern char hello[];“在别处有一块内存空间 ,名字叫 hello,里面存着字符。”你直接找到了那座房子
extern char *hello;“在别处有一个指针变量 ,名字叫 hello,里面存着一个地址。”你找到了一个信箱 ,里面写着房子的地址。

翻车现场:

如果你明明定义的是数组 char hello[] = "abc",却声明成了 extern char *hello

  • 当你使用*hello的时候,编译器会去 hello 的前几个字节里找“地址”。
  • 它会把 "abcd" 的 ASCII 码误认为是一个内存地址。
  • 结果:程序试图去访问一个乱七八糟的地址,直接 Segment Fault (段错误) 挂掉。

3. 场景三:main 函数的 argv

书里提到了 char *argv[]char **argv 的等价性。

  • argv 是一个 指针的数组 (存了一堆字符串地址的列表)。
  • 根据场景一的逻辑,当它作为 main 函数的参数时,它会“退化”成指向首元素的指针。
  • 因为数组里的每个元素本身就是 char *(指针),所以指向这些元素的指针就是 “指向指针的指针” ,即 char **

本章小结

111