繁体   English   中英

什么时候不需要typedef?

[英]When don't I need a 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中,如果你要写

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 ++中的含义不同。

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

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

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

struct mystruct {};

不能简单地将它称为mystruct。 相反,我必须指定我想要struct namespace中存在的mystruct:

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

从长远来看,这有点冗长和尴尬。 相反,您可以将其定义为默认命名空间:

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);

因此,您的第一个示例只是将这两个步骤合并在一起:声明一个结构,并将一个别名放入常规命名空间。 当然,既然我们无论如何都要对它进行类型化,我们不需要“原始”名称,因此我们可以使结构匿名。 在宣布之后

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

我们有一个没有名称的结构,它在默认名称空间中被“typedef”为“tagMyStruct”。

这就是C对待它的方式。 两种类型的声明都是有效的,但是没有在“默认”命名空间中创建别名,因此每次引用类型时都必须使用struct关键字。

在C ++中,单独的struct命名空间不存在,因此它们的含义相同。 (但较短的版本是首选)。

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

这只是速记。

在第二个实例中,要使用以下命令声明结构:

struct MyStruct a;

在第一个版本中,您可以这样做:

tagMyStruct a;

第二个变体也存在于C.

只要您想为类型命名,就可以使用第一个变体,例如:

tagEnum myFunc(tagMyStruct * myArg);

第一个可能在C ++中不方便,因为您无法在头文件中转发声明它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM