我正在学习C,而我正在阅读关于类型等价的内容。
我很好奇,有没有人知道他们为什么使用数组和指针的结构等价但他们使用结构和联合的声明等价?
为什么那里存在差距?对结构/联合做声明等价和其他一切的结构等价有什么好处?
答案 0 :(得分:5)
我确信其他人会提供C特定信息,但我会提到类型等价是编程语言理论中的经典主要问题之一。确定两种类型是否实际等效是一个比它看起来更棘手的问题。
例如,这里有一些overview slides from an academic course只是为了让您领略头痛。
答案 1 :(得分:4)
我确信这是因为当时看起来好主意。
不要试图过度思考C. Kernighan& amp;的设计。 Ritchie正在设计一种系统实现语言,这种语言可能对其他事情有好处,并且最终决定了他们后悔的决策(运算符优先级是最好的记录)。标准委员会已经清理了一些问题,其他问题则根深蒂固。
正如Uri在他的回答中所指出的那样,类型等价是一个难题,因此是K& R可能会因为希望尽快得到一个有效的编译器而不是一个干净的语言设计而受到惩罚的人之一。
答案 2 :(得分:3)
在很多方面,c是20世纪70年代的集合习语的清晰表达。这些处理器上的数组直接使用指针实现,而c只是复制 fact 。
答案 3 :(得分:3)
结构等同性很难检查。指针和数组非常简单,但结构和联合类型更复杂。在这些复杂类型上测试结构等价非常困难,但指针和数组更容易。
修改强>
最初我写了一个处理值等价而不是类型等价的答案,因此它并不能真正回答这个问题。不过,我确实收到了一些赞成票,所以我决定留在这里。
我对[值等价]的了解是,指针和数组在内存中总是有一个非常简单的布局。这使得进行简单的逐字节比较变得容易。
对于结构和联合,这种内存布局不一定非常简单。例如,您可以使用带有int(32位)和double(64位)的结构。这种结构需要128位存储器,其中32位实际上与比较无关。因此,字节替换比较是不可能的。因此,声明等效性更容易实现。
答案 4 :(得分:3)
不要低估Dennis Ritchie。每种静态类型语言都应该有一种方法来创建抽象类型,这是用户无法伪造的。为此,您需要一个 generative 的类型构造或声明构造,即构造的每个实例都会生成一个与其他任何实例不同的新类型。如果你想让其他人的手套远离你的数据,这样的结构是至关重要的。 (有很多例子,请参阅Dave Hanson的书C Interfaces and Implementations。)
所以这里的值p1
和p2
有不同的类型,但表示方式相同:
struct { float x, y } p1;
struct { float x, y } p2;
为什么选择struct
生成?因为它足够通用,可以提供各种方便的表示。 union
有点紧张,但我怀疑这是“抵押品设计”;在C的类型系统中,union
表现尽可能多的列表struct
,这简化了编译器。
顺便说一下,“声明等同”是我以前从未听过的术语。 25年前,诸如“名称对等”,“结构对等”和“出现等同”之类的术语很受欢迎。今天的类型系统更加正式,等价通常由逻辑规则而非非正式英语定义。当诉诸非正式英语有帮助时,我通常会发现“生成”的概念比为每种新语言的等价规则发明一个新名称具有更强的解释力。