7

最近我发现typedef我的代码中的工作与我提议的完全不同。像这样的一个例子:

typedef int *ptype;
ptype v1 = 0, v2 = 0;

结果:v1 和 v2 都被定义为指向int类型的指针。但是如果你只是简单地将第二句中的ptypeby替换为or ,那么只有 v1 将是指针,而 v2 是正常的。似乎没有做简单的替换。更重要的是,当涉及到复杂的修饰符时:int *int *v1 = 0, v2 = 0;int* v1 = 0, v2 =0;inttypedef

typedef int *ptype;
const ptype v3 = 0;

结果将是:v3 是一个const指针,如果我们写的话,它不是指向constint的指针const int *v3 = 0;。在上面的代码const中,代表整体的修饰符ptype,而不是int内部ptype。因此,它看起来真的像是typedef结合了复合类型int*并创建了一个新类型。

但是,权威的 C/C++ 参考网站cplusplus说“typedef 不会创建不同的类型。它只会创建现有类型的同义词”。所以我真的很困惑,希望有人可以帮助解释typedef. 谢谢!

4

3 回答 3

18

“同义词”并不意味着“文本替换”。ptype不是int *由预处理器或任何东西逐字扩展为。

这意味着您可以执行以下操作:

typedef int *ptype;
ptype a;
int *b;

a = b;   // OK

赋值是有效的,因为ptypeint *是相同的类型;不需要类型转换或强制转换。

typedef只是让您给现有类型一个新名称。但是该名称将现有类型的每个方面组合成一个不可分割的实体,例如,ptype a, b;等效于ptype a; ptype b;(并且const ptype表示“const 指向 int 的指针”,因为ptype表示“指向 int 的指针”)。

换句话说,就声明而言,由创建的新名称typedef表现得像内置关键字,但这些名称表示的实际类型是相同的。

于 2013-01-15T09:19:50.937 回答
2

当 cplusplus.com 说这typedef不会创建新类型时,他们的意思是在任何可以使用 value 的地方也可以使用ptypetype 的值,int*反之亦然。因此,如果您定义一个带ptype参数的函数,您可以传递它int*而无需任何转换。

这并不意味着 atypedef被实现为像 a 那样的纯文本替换#define

于 2013-01-15T09:18:53.470 回答
2

参考 C89,第 3.5 节,这ptype v1 = 0, v2 = 0;是不等同于int *v1 = 0, v2 = 0;. 更高版本的 C 和 C++ 是由 C89 提供的,在这方面基本相同。

ptype v1 = 0, v2 = 0;中,ptype是“声明说明符”,并且v1 = 0, v2 = 0是“初始化声明符列表”。具体来说,ptype是一个“类型说明符”,更具体地说,它是一个“typedef-name”。因此,我们声明了两个变量 (v1v2),它们都具有 type ptype,这是int*.

int* v1 = 0, v2 = 0,int*不是“声明说明符”,因为它由一系列“类型说明符”、“存储类说明符”和“类型限定符”组成。您可以依次查找其中的每一个,但将它们放在一起相当于一个完整的关键字列表,例如staticor const,内置类型名称,加上 typedef 和 enum 名称以及结构/联合说明符。它们包括*,这是复合类型语法的一部分。所以在这种情况下int是“声明说明符并且*v1 = 0, v2 = 0是”init-declarator list“。一旦我们分解“init-declarator list”的语法,*它只适用于v1,而不适用于v2。那'int*int

类似地,您可以编写ptype *v1 = 0, v2 = 0;,它将定义 onepytpe*和 one ptype。也就是说,一int**加一int*

const int *vs的语法const ptype得出了类似的结果——在前者中,const“类型限定符”适用于,int但在后者中适用于ptype.

于 2013-01-15T10:39:55.857 回答