我遇到了一些读码何时不需要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; };
是真的吗?你什么时候需要第一个变体?
我遇到了一些读码何时不需要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; };
是真的吗?你什么时候需要第一个变体?
首先,这两个声明在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#意义上的命名空间。
这只是速记。
在第二种情况下,申报你会做这样结构用:
struct MyStruct a;
在第一变,你会这样写:
tagMyStruct a;
它也是C的缩写吗?或者你只提到C++? – xtofl 2009-02-05 15:58:03
第二个变体还存在于C.
,只要你希望把你的类型,例如可以使用第一种变体:
tagEnum myFunc(tagMyStruct * myArg);
第一个可能在C++中不方便,因为你不能在一个头文件中转发它。
在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++中的不同。
将“只需要写入”版本是“tagMyStruct ...”ISO“MyStruct”?或者这是正确的? (这是违反直觉的......) – xtofl 2009-02-05 15:57:29
好的解释 – Eclipse 2009-02-05 16:49:49