Q如果它们如此不同,那么为什么数组和指针声明可以作为函数形式参数互换使用?
A这是一种便利。
由于数组会立即“衰退”为指针,因此实际上永远不会将数组传递给函数。您可以假装函数接收一个数组作为参数,并通过将相应参数声明为数组来演示这一点。
void f(char a[]) { ... }如果按字面意思解释,这种声明将毫无用处,因此编译器会将其视为您编写了指针声明,因为这正是函数实际将收到的内容。
void f(char *a) { ... }将函数视为“接收”数组并没有什么特别错误,如果该函数传统上用于操作数组,或者该参数在函数内部自然地被视为数组。
这种数组状声明符到指针的转换仅在函数形式参数声明中有效,其他任何地方无效。如果这种转换让您感到困扰,您没有义务使用它;许多程序员认为它造成的混淆抵消了让声明“看起来像”调用或函数内部使用方式的微小优势。(请注意,转换只发生一次;像char a2[][]这样的声明将不起作用。请参阅问题 6.18 和 6.19。)
另请参阅问题 6.21。
参考:K&R1 第 5.3 节,第 95 页,第 A10.1 节,第 205 页
K&R2 第 5.3 节,第 100 页,第 A8.6.3 节,第 218 页,第 A10.1 节,第 226 页
ISO 第 6.5.4.3 节,第 6.7.1 节,第 6.9.6 节
H&S 第 9.3 节,第 271 页
CT&P 第 3.3 节,第 33-34 页
Dennis Ritchie,“C 语言的发展”