c - 为什么 type arrayp[] 与 type* arrayp 作为函数的参数相同?
问题描述
为什么 feint arrayp[]
与int* arrayp
, 作为函数定义/声明中的参数相同?
int* foo(int arrayp[]){}
指向int
作为参数传递给调用者的数组的第一个元素的指针。
像:
#include <stdio.h>
int* foo (int arrayp[]);
int main(void)
{
int a[] = { 10,5,4,2,1 };
int *p;
p = foo(a);
printf("%d",*p);
return 0;
}
int* foo(int arrayp[])
{
*arrayp = 0;
return arrayp;
}
为什么int arrayp[]
指向类型数组的第一个元素的指针int
?恕我直言,我认为这非常令人困惑。有些人可能认为他们用这个表达式传递了一个完整的数组(按值传递)。
解决方案
在函数参数类型中,数组被隐式调整为它们将衰减到的指针。
因此,例如,这些函数声明对是兼容的:
void foo(int a[]);
void foo(int *a); //compatible declaration
void bar(int a[][2][3]);
void bar(int (*a)[2][3]); //compatible declaration
Dennis Ritchie(语言作者)在https://www.bell-labs.com/usr/dmr/www/chist.html中解释了这个令人困惑的规则
此外,一些旨在缓解早期过渡的规则导致了后来的混乱。例如,函数声明中的空方括号
int f(a) int a[]; { ... } 是活化石,是 NB 声明指针方式的残余;a 仅在这种特殊情况下,在 C 中被解释为指针。该符号之所以得以保留,部分原因是为了兼容性,部分原因是因为它允许程序员向他们的读者传达传递从数组生成的 fa 指针的意图,而不是对单个整数的引用。不幸的是,它既使学习者感到困惑,也使读者警觉。
(注意:Chist.html 使用 K&R 风格的函数定义。上述函数定义的原型等效项是int f( int a[]){ ... }
.)
简而言之,该规则的存在主要是为了简化从 B 到 C 的转换,并允许程序员向读者发出信号,指出需要指向数组第一个元素的指针,而不仅仅是指向单个元素的指针(并且这样做无需使用评论)。
函数类型的参数也以类似的方式调整为指针。
void takeFuncPtr(void Func(void));
void takeFuncPtr(void (*Func)(void)); //compatible declaration
一个可能更深层次的问题是“为什么数组在 C 中完全衰减为指针”?链接的文档也提供了该问题的答案:
...这些语义代表了从 B 的简单过渡,我用它们做了几个月的试验。当我尝试扩展类型表示法,尤其是添加结构化(记录)类型时,问题变得很明显。结构似乎应该以直观的方式映射到机器的内存中,但是在包含数组的结构中,没有好地方来存放包含数组基数的指针,也没有任何方便的方法来安排它初始化。例如,早期 Unix 系统的目录条目可能在 C 中描述为
结构 { int innumber; 字符名称[14];};
我希望该结构不仅可以表征抽象对象,还可以描述可能从目录中读取的位集合。编译器可以在哪里隐藏语义要求的名称指针?即使结构被认为更抽象,并且指针的空间可以以某种方式隐藏,我如何处理在分配复杂对象时正确初始化这些指针的技术问题,也许是一个指定结构包含包含任意深度结构的数组的结构?该解决方案构成了无类型 BCPL 和有类型 C 之间进化链中的关键跳跃。它消除了指针在存储中的物化,而是在表达式中提到数组名称时导致创建指针。规则,
...
推荐阅读
- opengl - 设置 gl_FragDepth 会导致延迟?
- php - 根据每个数组中的键值合并到数组的最佳方法是什么?
- javascript - 如何从每个唯一的 Firestore 文档中检索 1 个图片 URL 并使用该 picURL 设置 img.src?
- excel - Mac Excel 2016 (16.36) 上的 Excel VBA 运行时错误 1004
- c++ - C++ 之间的区别:Obj*& vs Obj** vs Obj&&
- amazon-s3 - Kafka-Connect:启动 S3 Sink 连接器时出现无法识别的错误
- node.js - 无法下载所有 reactjs 包。只获取 node_modules、package-lock.json 和 package.json
- java - 为什么这个整数比较给出相等的引用?
- javascript - 从一组数据中去除异常值并使用javascript使数据保持一致的准确方法是什么?
- rust - 调用合约失败