为什么 #define 和 typedef 操作数颠倒?
以下定义 A
将替换为 B
:
#define A B
而这将 A
定义为 B 的别名>类型 B
:
typedef B A;
为什么?这不是语无伦次吗?
The following defines A
to be replaced by B
:
#define A B
Whereas this defines A
to be an alias for the type B
:
typedef B A;
Why ? Isn't this incoherent ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
简单地说:考虑以下变量声明:
那么
typedef
就非常有意义:另一方面,宏可以采用函数式语法:
因此对于宏来说,后面的“定义” “名字”更有意义。
(顺便说一句,这也适用于 C++。)
Simply put: consider the following variable declarations:
Then the
typedef
s make perfect sense:Macros, on the other hand, can take on a function-style syntax:
So for macros, the "definition" coming after the "name" makes more sense.
(This applies to C++ too, by the way.)
是的,宏几乎是一团糟。
typedef
在该语言的大部分其余部分完成后很长一段时间才被添加到该语言中。它使用与存储类相同的语法:它们将
x
、y
和z
定义为int
- - 区别在于x
和y
是int
类型的对象,而z
基本上是的别名code>int
本身。因此,
typedef
相当适合该语言,并且(像往常一样)预处理器才是真正的“奇怪的人”。同时,您可能会认为语言的其余部分也应该改变。仅举一个明显的例子,帕斯卡大致颠倒了事情的顺序:虽然它对于琐碎的示例没有太大区别,但我认为这更容易阅读,特别是当您处理更复杂的声明时。然而,无论好坏,Pascal(大部分)已经失宠,而像 Java 这样的较新语言保留了 C 语法的这一特定部分(即,它们保留的 C 部分是最需要更改的一件事) 。
Yes, macros are pretty much a mess.
typedef
was added to the language quite a while after most of the rest of the language was complete. It uses the same syntax as a storage class:These define
x
,y
andz
as all beingint
-- the difference is thatx
andy
are objects of typeint
, andz
is basically an alias forint
itself.As such,
typedef
fits with the language proper reasonably well, and it's (as usual) the preprocessor that's really the "odd man out." At the same time, you could argue that the rest of the language should change as well. Just for an obvious example, Pascal roughly reversed the order of things:While it doesn't make a lot of difference for trivial examples, I think this is rather simpler to read, especially when you deal with more complex declarations. For better or worse, however, Pascal has (mostly) fallen out of favor, and newer languages like Java have retained this particular part of C syntax (i.e., the part of C they kept was the one thing most in need of being changed).
因为
typedef
中的A
可以是多个符号,例如typedef int Integer, *PInteger;
。这与变量的定义方式一致(
int var, *pvar;
)。Because
A
intypedef
can be multiple symbols, e.g.typedef int Integer, *PInteger;
.This is consistent with how variables are defined (
int var, *pvar;
).从语言语法的角度来看,typedef 与
extern
和static
(*) 一起位于存储类说明符
组中,因此 typedef 具有与那些相同的位置。它显然不属于这个组,但我猜它可能是最不被放错的地方。(*)
存储类还包括
auto
和register
,但没有人再使用它们了。Typedef is from a language syntax point of view in the
storage class specifier
group together withextern
andstatic
(*), and thus typedef has the same placement as those. It does not obviously belong to this group, but I guess it was probably where it was least mis-placed.(*)
Storage class also includes
auto
andregister
, but nobody uses those any more.我不知道为什么就语言决定而言,但 typedef 的方式对我来说是有意义的。
typedef
说明符是语言的一部分。它是一种将类型别名为某个名称的方法。您始终可以在变量声明中内联类型。使用
typedef
反映了这种用法,只不过您不是声明类型的变量,而是声明类型的名称。#define 指令是预处理器的一部分,而不是语言的一部分,因此它不受语言表示某些构造的方式的限制,并且可以使用更自然的方式来声明它。
I don't know why as far as the language decisions are concerned, but the way typedef is makes sense to me.
The
typedef
specifier is part of the language. It serves as a way to alias a type to some name. You could always inline what the type is in a variable declaration.Using
typedef
mirrors this use except instead of declaring a variable to the type, you're declaring a name for the type.The
#define
directive is part of the preprocessor and not of the language so it isn't bound to the way the language represents certain constructs and can use the more natural way of declaring it.因为预处理器和编译器实际上是两个不同的程序,每个程序都有自己的语法。人们可以毫不费力地将预处理器与其他语言结合起来(实际上,我以前是通过在 dBase III 程序和 AutoLISP 上使用 cpp 来做到这一点的,因为这些语言缺乏良好的常量包含机制)。
正如其他人已经指出的,
typedef
遵循 C 声明系统的语法,而#define
是一个简单直接的替换声明。Because the pre-processor and the compiler are in fact two different programs, each with its own syntax. One could combine the preprocessor with other languages with not too much difficulty (I actually did that in older times by using
cpp
on dBase III programs and on AutoLISP because these languages lacked a good include mechanism for constants).As others have already pointed out,
typedef
follows the syntax of the declaration system of C and#define
is a simple straight-forward declaration of substitution.是的,typedef 语法也让我有点困惑。我认为你的问题更多的是抱怨 - C 已经快 40 岁了,你不希望 typedef 语法改变,是吗?
Yes, typedef syntax tends to throw me off a little as well. I assume that your question is more of a complaint - C is almost 40 years old, you do not expect the typedef syntax to change, do you?