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

byqmnocz  于 2023-01-12  发布在  其他
关注(0)|答案(3)|浏览(167)

考虑:

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

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

gfttwv5a

gfttwv5a1#

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

typedef关键字是一个伪存储类说明符。从语法上讲,它与externstatic等存储类说明符的使用位置相同。它与存储无关。这意味着声明不引入named objects的存在,而是引入类型别名的名称。
在上述声明之后,State标识符变成了类型enum state {DEAD,ALIVE}的别名。声明也提供了该类型本身。然而,这不是typedef做的。任何enum state {DEAD,ALIVE}作为类型说明符出现的声明都会将该类型引入作用域:

enum state {DEAD, ALIVE} stateVariable;

如果enum state之前已经被引入,则typedef必须写成这样:

typedef enum state State;

否则enum正在被重新定义,这是一个错误。
和其他声明一样(除了函数参数声明),typedef声明可以有多个声明符,用逗号分隔。而且,它们可以是派生声明符,而不仅仅是简单的名称:

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

这个typedef引入了两个类型名ulongulongptr,它们基于在说明符-限定符列表中给出的unsigned long类型。ulong只是该类型的一个直接别名。ulongptr被声明为指向unsigned long的指针,这要归功于*语法,它在这个角色中是一种类型构造运算符,它有意地模仿一元*用于表达式中使用的指针解引用。换句话说,ulongptr是“指向unsigned long的指针“类型的别名。
别名表示ulongptr不是unsigned long *的不同类型。这是有效代码,不需要诊断:

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

变量qp具有完全相同的类型。
typedef的别名不是文本的,例如,如果user_id_tint类型的typedef名称,我们不能简单地这样做:

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

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

#define user_id_t int
unsigned user_id_t uid;

由此在语法分析和翻译之前将user_id_t宏扩展为标记int。虽然这看起来像是优点,但却是错误的;在新程序中避免这种情况。
它不适用于派生类型的缺点包括:

#define silly_macro int *

 silly_macro not, what, you, think;

此声明没有将whatyouthink声明为“int指针”类型,因为宏扩展为:

int * not, what, you, think;

类型说明符是int,声明符是*notwhatyouthink,因此not具有预期的指针类型,但其余标识符没有。
这大概是C语言中typedef和类型别名的99%。

k7fdbhmy

k7fdbhmy2#

typedef定义了一个新的数据类型,因此您可以:

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

现在你可以用这些新的数据类型声明变量了

my_string s;
my_struct x;

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

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

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

使用typedef 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
   }
}
wbgh16ku

wbgh16ku3#

一个 typedef,只是个别名-

  • “typedef是编程语言C和C++中的保留关键字。它用于为另一个数据类型创建附加名称alias),但不创建新类型”(Wiki
  • “typedef声明提供了一种方法将标识符声明为类型别名,以 * 用于替换 * 可能的复杂类型名称”(cppreference

相关问题