2009-02-05 48 views
5

我遇到了一些读码何时不需要typedef?

typedef enum eEnum { c1, c2 } tagEnum; 

typedef struct { int i; double d; } tagMyStruct; 

我听到传言,这些结构从C.日期在C++中,你可以很容易地编写

enum eEnum { c1, c2 }; 
struct MyStruct { int i; double d; }; 

是真的吗?你什么时候需要第一个变体?

回答

10

首先,这两个声明在C和C++都是合法的。但是,在C语言中,它们有稍微不同的语义。 (特别是,你后来引用结构体的方式会有所不同)。

理解的关键概念是在C中,结构存在于一个单独的名称空间中。 所有内置类型以及typedef都存在于“默认”命名空间中。也就是说,当我输入int时,编译器只检查这个“默认”命名空间。如果我在你的例子中键入“tagMyStruct”,编译器也只检查这个命名空间。但是,根据您使用哪种类型的声明,该结构可能不存在于该名称空间中。

结构不同,存在于单独的名称空间中。所以,如果我做如下声明:

struct mystruct {}; 

简单地将其称为MYSTRUCT。相反,我必须指定我想要存在于struct命名空间中的mystruct:

void foo(struct mystruct bar); // Declare a function which takes a mystruct as its parameter 

从长远来看,它有点冗长和尴尬。相反,你可以的typedef它变成默认的命名空间:

typedef struct mystruct mystruct; // From now on, 'mystruct' in the normal namespace is an alias for 'mystruct' in the struct namespace 

,现在,我的功能,可以在简单的方式声明:

void foo(mystruct bar); 

所以,你的第一个例子简单合并这两个步骤一起:声明一个结构,并将一个别名放入常规名称空间。当然,因为无论如何我们都在对它进行typedeff,所以我们不需要“原始”名称,所以我们可以使结构匿名。所以,你的宣言

typedef struct { int i; double d; } tagMyStruct; 

后,我们有没有名字,已Typedef的在默认命名空间“tagMyStruct”一个结构。

这就是C如何对待它。这两种声明都是有效的,但是不会在“默认”命名空间中创建别名,所以每次引用该类型时都必须使用struct关键字。

在C++中,单独的struct命名空间不存在,所以它们的意思是相同的。 (但较短的版本是首选)。

编辑要明确,不,C没有名称空间。不是通常意义上的。 C只需将标识符置于两个预定义的名称空间之一中。我记得结构体(和枚举)的名称被放在一个中,而所有其他标识符放在另一个中。从技术上讲,这些是命名空间,因为它们是单独的“容器”,其中放置名称以避免冲突,但它们当然不是C++/C#意义上的命名空间。

+0

好的解释 – Eclipse 2009-02-05 16:49:49

1

这只是速记。

在第二种情况下,申报你会做这样结构用:

struct MyStruct a; 

在第一变,你会这样写:

tagMyStruct a; 
+0

它也是C的缩写吗?或者你只提到C++? – xtofl 2009-02-05 15:58:03

0

第二个变体还存在于C.

,只要你希望把你的类型,例如可以使用第一种变体:

tagEnum myFunc(tagMyStruct * myArg); 
0

第一个可能在C++中不方便,因为你不能在一个头文件中转发它。

10

在C,如果你写

struct MyStruct { int i; double d; }; 

,只要你想引用类型,你必须指定你在谈论一个结构:

struct MyStruct instanceOfMyStruct; 
struct MyStruct *ptrToMyStruct; 

随着typedef的版本:

typedef struct { int i; double d; } tagMyStruct; 

你只需要编写:

tagMyStruct instanceOfMyStruct; 
tagMyStruct *ptrToMyStruct; 

typedef'd版本的另一个重大优势是,您可以在C和C++中以相同的方式引用结构,而在第二个版本中,它们在C中的引用与C++中的不同。

+0

将“只需要写入”版本是“tagMyStruct ...”ISO“MyStruct”?或者这是正确的? (这是违反直觉的......) – xtofl 2009-02-05 15:57:29