[英]How do I use typedef and typedef enum in C?
Consider:考虑:
#define MAXROW 20
#define MAXCOL 60
typedef State Grid[MAXROW+2] [MAXCOL+2]
typedef enum state {DEAD,ALIVE} State
How do I use typedef
and typedef enum
in C?如何在 C 中使用
typedef
和typedef enum
? What does this part of the code do?这部分代码的作用是什么?
typedef enum state {DEAD,ALIVE} State;
| | | | | |^ terminating semicolon, required!
| | | type specifier | | |
| | | | ^^^^^ declarator (simple name)
| | | |
| | ^^^^^^^^^^^^^^^^^^^^^^^
| |
^^^^^^^-- storage class specifier (in this case typedef)
The typedef
keyword is a pseudo-storage-class specifier. typedef
关键字是伪存储类说明符。 Syntactically, it is used in the same place where a storage class specifier like extern
or static
is used. 从语法上讲,它用于使用
extern
或static
等存储类说明符的相同位置。 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 .
这意味着声明不会引入命名对象的存在,而是引入了类型别名的名称。
After the above declaration, the State
identifier becomes an alias for the type enum state {DEAD,ALIVE}
. 在上述声明之后,
State
标识符成为类型enum state {DEAD,ALIVE}
的别名。 The declaration also provides that type itself. 声明还提供了类型本身。 However that isn't
typedef
doing it. 但是,这不是
typedef
。 Any declaration in which enum state {DEAD,ALIVE}
appears as a type specifier introduces that type into the scope: enum state {DEAD,ALIVE}
作为类型说明符出现的任何声明都会将该类型引入范围:
enum state {DEAD, ALIVE} stateVariable;
If enum state
has previously been introduced the typedef
has to be written like this: 如果先前已经引入了
enum state
则必须像这样编写typedef
:
typedef enum state State;
otherwise the enum
is being redefined, which is an error. 否则
enum
被重新定义,这是一个错误。
Like other declarations (except function parameter declarations), the typedef
declaration can have multiple declarators, separated by a comma. 与其他声明(函数参数声明除外)一样,
typedef
声明可以有多个声明符,用逗号分隔。 Moreover, they can be derived declarators, not only simple names: 而且,它们可以是派生的声明符,而不仅仅是简单的名称:
typedef unsigned long ulong, *ulongptr;
| | | | | 1 | | 2 |
| | | | | | ^^^^^^^^^--- "pointer to" declarator
| | | | ^^^^^^------------- simple declarator
| | ^^^^^^^^^^^^^-------------------- specifier-qualifier list
^^^^^^^---------------------------------- storage class specifier
This typedef
introduces two type names ulong
and ulongptr
, based on the unsigned long
type given in the specifier-qualifier list. 这个
typedef
引入了两个类型名称ulong
和ulongptr
,它们基于说明符限定符列表中给出的unsigned long
类型。 ulong
is just a straight alias for that type. ulong
只是该类型的直接别名。 ulongptr
is 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. ulongptr
被声明为指向unsigned long
的指针,这要归功于*
语法,该语法在这个角色中是一种类型构造运算符,故意模仿表达式中使用的指针解除引用的一元*
。 In other words ulongptr
is an alias for the "pointer to unsigned long
" type. 换句话说,
ulongptr
是“指向unsigned long
”类型的别名。
Alias means that ulongptr
is not a distinct type from unsigned long *
. 别名意味着
ulongptr
不是 unsigned long *
的独特类型 。 This is valid code, requiring no diagnostic: 这是有效的代码,无需诊断:
unsigned long *p = 0;
ulongptr q = p;
The variables q
and p
have exactly the same type. 变量
q
和p
具有完全相同的类型。
The aliasing of typedef
isn't textual. typedef
的别名不是文本的。 For instance if user_id_t
is a typedef
name for the type int
, we may not simply do this: 例如,如果
user_id_t
是int
类型的typedef
名称,我们可能不会简单地这样做:
unsigned user_id_t uid; // error! programmer hoped for "unsigned int uid".
This is an invalid type specifier list, combining unsigned
with a typedef name. 这是一个无效的类型说明符列表,将
unsigned
与typedef名称相结合。 The above can be done using the C preprocessor: 以上可以使用C预处理器完成:
#define user_id_t int
unsigned user_id_t uid;
whereby user_id_t
is macro-expanded to the token int
prior to syntax analysis and translation. 从而在语法分析和转换之前将
user_id_t
宏扩展到标记int
。 While this may seem like an advantage, it is a false one; 虽然这似乎是一种优势,但却是假的; avoid this in new programs.
在新程序中避免这种情况。
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
, you
and think
as 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
, you
and think
. 类型说明符是
int
,声明符是*not
, what
, you
和think
。 So not
has the expected pointer type, but the remaining identifiers do not. 所以
not
预期的指针类型,但其余的标识符没有。
And that's probably 99% of everything about typedef
and type aliasing in C. 这可能是关于
typedef
和C语言类型别名的99%。
typedef
defines a new data type. typedef
定义了一种新的数据类型。 So you can have: 所以你可以:
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 enum
creates an alias for a type: 使用
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
}
}
A typedef , is just an alias - typedef只是一个别名-
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.