4

我正在学习 C 并且正在阅读关于类型等价的内容。

我很好奇,有没有人有意见,为什么他们对数组和指针使用结构等价,但对结构和联合使用声明等价?

为什么会有差距?使用结构/联合进行声明等效以及对其他所有内容进行结构等效有什么好处?

4

5 回答 5

5

我相信其他人会提供 C 特定的信息,但我会提到类型等价是编程语言理论中的经典主要问题之一。确定两种类型实际上是否等效是一个比看起来要复杂得多的问题。

例如,这里有一些来自学术课程的概述幻灯片,只是为了让您体验一下头痛。

于 2009-04-27T20:09:36.027 回答
4

我敢肯定这是因为它在当时看起来是个好主意。

不要试图过度思考 C. Kernighan 和 Ritchie 的设计,他们正在设计一种可能对其他事情有好处的系统实现语言,并最终做出了他们后来后悔的决定(操作员优先级是最好的文档)。有些问题已经被标准委员会清理了,有些则根深蒂固。

正如 Uri 在他的回答中指出的那样,类型等价是一个难题,因此可能是 K&R 为了尽快获得工作编译器而不是稍后获得干净的语言设计而抨击的问题之一。

于 2009-04-27T20:11:48.160 回答
3

在很多方面,c 都是 1970 年代汇编语言的简洁表达。这些处理器上的数组是直接使用指针实现的,而 c 只是简单地复制了这个fact

于 2009-04-27T20:12:56.313 回答
3

结构等价性很难检查。指针和数组非常简单,但结构和联合类型更复杂。在这些复杂类型上测试结构等价是非常困难的,但对于指针和数组来说更容易。

编辑

最初我写了一个处理值等价而不是类型等价的答案,所以它并不是这个问题的真正答案。不过,我确实收到了一些赞成票,所以我决定留在这里。

我对 [值等价] 的了解是,指针和数组在内存中总是有一个非常简单的布局。这使得进行简单的逐字节比较变得容易。

对于结构体和联合体,这种内存布局不一定这么简单。例如,您可以拥有一个带有 int(32 位)和 double(64 位)的结构。这样的结构需要 128 位内存,其中 32 位实际上与比较无关。因此,逐字节比较是不可能的。因此,声明等价更容易实现。

于 2009-04-27T20:21:35.483 回答
3

不要低估丹尼斯·里奇。每种静态类型语言都应该有一种方法来创建用户无法伪造的抽象类型。为此,您需要一个可生成的类型构造或声明构造即构造的每个实例都会生成一个新类型,与其他类型不同。如果您想让其他人对您的数据不闻不问,那么这种结构至关重要。(有关大量示例,请参阅 Dave Hanson 的书C 接口和实现。)

所以这里的值p1p2具有不同的类型但相同的表示:

struct { float x, y } p1;
struct { float x, y } p2;

为什么选择struct生成?因为它足够通用,可以进行广泛的方便表示。 union有点牵强,但我怀疑这是“附带设计”;在 C 的类型系统中,union行为尽可能多的列表struct,这简化了编译器。

顺便说一句,“声明等效”是我以前从未听说过的术语。25 年前,“名称等价”、“结构等价”和“出现等价”等术语很流行。今天的类型系统更加正式,等价通常由逻辑规则而不是非正式的英语定义。当求助于非正式英语有帮助时,我通常发现“生成性”的概念比为每种新语言的等价规则发明一个新名称更具有解释力。

于 2009-04-28T02:25:21.693 回答