C语言 如何在 C 中使用 typedef 和 typedef 枚举?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20426716/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 10:28:06  来源:igfitidea点击:

How do I use typedef and typedef enum in C?

ctypedef

提问by user39555

Consider:

考虑:

#define MAXROW 20
#define MAXCOL 60
typedef State Grid[MAXROW+2] [MAXCOL+2]
typedef enum state {DEAD,ALIVE} State

How do I use typedefand typedef enumin C? What does this part of the code do?

我如何在 C 中使用typedeftypedef enum?这部分代码有什么作用?

回答by Kaz

typedef enum state {DEAD,ALIVE} State;
|     | |                     | |   |^ terminating semicolon, required! 
|     | |   type specifier    | |   |
|     | |                     | ^^^^^  declarator (simple name)
|     | |                     |    
|     | ^^^^^^^^^^^^^^^^^^^^^^^  
|     |
^^^^^^^-- storage class specifier (in this case typedef)

The typedefkeyword is a pseudo-storage-class specifier. Syntactically, it is used in the same place where a storage class specifier like externor staticis used. It doesn't have anything to do with storage. It means that the declaration doesn't introduce the existence of named objects, but rather, it introduces names which are type aliases.

typedef关键字是伪存储类说明。从语法上讲,它与使用存储类说明符(如externstatic)相同的地方使用它。它与存储没有任何关系。这意味着声明没有引入命名对象的存在,而是引入了类型别名的名称。

After the above declaration, the Stateidentifier becomes an alias for the type enum state {DEAD,ALIVE}. The declaration also provides that type itself. However that isn't typedefdoing it. Anydeclaration in which enum state {DEAD,ALIVE}appears as a type specifier introduces that type into the scope:

在上述声明之后,State标识符成为 type 的别名enum state {DEAD,ALIVE}。该声明还提供了该类型本身。然而,这不是typedef这样做的。任何enum state {DEAD,ALIVE}作为类型说明符出现的声明都会将该类型引入范围:

enum state {DEAD, ALIVE} stateVariable;

If enum statehas previously been introduced the typedefhas to be written like this:

如果enum state之前已经介绍过,typedef则必须这样写:

typedef enum state State;

otherwise the enumis being redefined, which is an error.

否则将enum被重新定义,这是一个错误。

Like other declarations (except function parameter declarations), the typedefdeclaration can have multiple declarators, separated by a comma. Moreover, they can be derived declarators, not only simple names:

与其他声明(函数参数声明除外)一样,typedef声明可以有多个声明符,以逗号分隔。此外,它们可以是派生声明符,而不仅仅是简单的名称:

typedef unsigned long ulong, *ulongptr;
|     | |           | |  1 | |   2   |
|     | |           | |    | ^^^^^^^^^--- "pointer to" declarator
|     | |           | ^^^^^^------------- simple declarator
|     | ^^^^^^^^^^^^^-------------------- specifier-qualifier list
^^^^^^^---------------------------------- storage class specifier

This typedefintroduces two type names ulongand ulongptr, based on the unsigned longtype given in the specifier-qualifier list. ulongis just a straight alias for that type. ulongptris declared as a pointer to unsigned long, thanks to the *syntax, which in this role is a kind of type construction operator which deliberately mimics the unary *for pointer dereferencing used in expressions. In other words ulongptris an alias for the "pointer to unsigned long" type.

这基于说明符-限定符列表中给出的类型typedef引入了两个类型名称ulong和。只是该类型的直接别名。被声明为指向 的指针,这要归功于语法,它在这个角色中是一种类型构造运算符,它故意模仿表达式中使用的指针解引用的一元。换句话说,是“指向”类型的别名。ulongptrunsigned longulongulongptrunsigned long**ulongptrunsigned long

Alias means that ulongptris not a distinct typefrom unsigned long *. This is valid code, requiring no diagnostic:

别名意味着ulongptr是不是一个独特的类型unsigned long *。这是有效的代码,不需要诊断:

unsigned long *p = 0;
ulongptr q = p;

The variables qand phave exactly the same type.

变量qp具有完全相同的类型。

The aliasing of typedefisn't textual. For instance if user_id_tis a typedefname for the type int, we may not simply do this:

的别名typedef不是文本的。例如,如果user_id_ttypedeftype的名称int,我们可能不会简单地这样做:

unsigned user_id_t uid;  // error! programmer hoped for "unsigned int uid". 

This is an invalid type specifier list, combining unsignedwith a typedef name. The above can be done using the C preprocessor:

这是一个无效的类型说明符列表,结合unsigned了一个 typedef 名称。以上可以使用 C 预处理器完成:

#define user_id_t int
unsigned user_id_t uid;

whereby user_id_tis macro-expanded to the token intprior to syntax analysis and translation. While this may seem like an advantage, it is a false one; avoid this in new programs.

在语法分析和翻译之前,其中user_id_t宏扩展到令牌int。虽然这看起来是一种优势,但它是错误的。在新程序中避免这种情况。

Among the disadvantages that it doesn't work well for derived types:

它不适用于派生类型的缺点包括:

 #define silly_macro int *

 silly_macro not, what, you, think;

This declaration doesn't declare what, youand thinkas being of type "pointer to int" because the macro-expansion is:

这个声明没有声明what,you并且think是“指向 int 的指针”类型,因为宏扩展是:

 int * not, what, you, think;

The type specifier is int, and the declarators are *not, what, youand think. So nothas the expected pointer type, but the remaining identifiers do not.

该类型说明符是int,和说明符*notwhatyouthink。所以not有预期的指针类型,但是剩余的标识符不。

And that's probably 99% of everything about typedefand type aliasing in C.

这可能是typedefC 中关于别名和类型别名的所有内容的 99% 。

回答by Pandrei

typedefdefines a new data type. So you can have:

typedef定义新的数据类型。所以你可以有:

typedef char* my_string;
typedef struct{
  int member1;
  int member2;
} my_struct;

So now you can declare variables with these new data types

所以现在您可以使用这些新数据类型声明变量

my_string s;
my_struct x;

s = "welcome";
x.member1 = 10;

For enum, things are a bit different - consider the following examples:

对于enum,情况有点不同 - 请考虑以下示例:

enum Ranks {FIRST, SECOND};
int main()
{
   int data = 20;
   if (data == FIRST)
   {
      //do something
   }
}

using typedef enumcreates an alias for a type:

usingtypedef enum创建一个类型的别名:

typedef enum Ranks {FIRST, SECOND} Order;
int main()
{
   Order data = (Order)20;  // Must cast to defined type to prevent error

   if (data == FIRST)
   {
      //do something
   }
}