我如何使用typedef,并用C的typedef枚举? [英] How do I use typedef and typedef enum in C?

查看:220
本文介绍了我如何使用typedef,并用C的typedef枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑:

 的#define的MaxRow 20
#定义60 MAXCOL
typedef的国家电网[+的MaxRow 2] [MAXCOL + 2]
的typedef枚举{状态DEAD,ALIVE}国家

我如何使用的typedef 的typedef枚举用C?什么是code,这部分怎么办?


解决方案

 的typedef枚举{状态DEAD,ALIVE}国;
| | | | | | ^终止分号,要求!
| | |类型说明符| | |
| | | | ^^^^^声明符(简单名称)
| | | |
| | ^^^^^^^^^^^^^^^^^^^^^^^
| |
^^^^^^^ - 存储类说明(在本例中的typedef)

的typedef 关键字是一个伪存储类说明。在语法上,它在如的extern存储类说明静态使用了相同的地方被使用。它没有任何与存储。这意味着,该声明不引入​​的命名对象的存在,而是,它引入了它们的名称类型别名

上面的声明之后,国家标识符成为一个别名键入枚举状态{死,活活} 。该宣言还提供了类型本身。然而这不是的typedef 这样做。 任何的声明中,枚举状态{死,活活} 显示为一个类型说明符引入了类型转换的范围:

 枚举状态{死,活活} stateVariable;

如果枚举状态有previously被引入了的typedef 已被写成这样:

 的typedef枚举状态的国家;

,否则枚举正在被重新定义,这是一个错误。

像其他的声明(除函数参数声明),在的typedef 声明可以有多个声明,用逗号分隔。此外,它们可以衍生说明符,不仅简单名称

 的typedef无符号长ULONG,* ulongptr;
| | | | | 1 | | 2 |
| | | | | | ^^^^^^^^^ ---指针声明符
| | | | ^^^^^^ -------------简单的声明符
| | ^^^^^^^^^^^^^ --------------------说明符限定符列表
^^^^^^^ ----------------------------------存储类说明

的typedef 介绍了两种类型的名称 ULONG ulongptr ,根据无符号长键入说明符限定符列表给出。 ULONG 就是该类型直别名。 ulongptr 被声明为一个指向无符号长,由于 * 语法,在这个角色是一种建筑类型运营商的蓄意模仿一元 * 为指针前pressions取消引用使用。换句话说 ulongptr 是一个别名指向无符号长的类型。

别名意味着 ulongptr 不是一个不同于键入无符号长* 。这是有效的code,无需诊断:

 无符号长* P = 0;
ulongptr * Q = P;

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

的typedef 的别名是不是文字。例如,如果 user_id_t 是类型的typedef 名称 INT ,我们可能不能简单地做到这一点:

 无符号user_id_t UID; //错误!程序员希望无符号整型UID。

这是一个无效的类型说明符列表,无符号结合typedef名。以上可以使用C preprocessor来完成:

 的#define user_id_t INT
无符号user_id_t UID;

user_id_t 是宏扩展到令牌 INT 之前语法分析和翻译。虽然这可能看起来像一个优势,这是错误的;避免这种情况在新的方案。

其中的缺点是它不为派生类型工作良好:

 的#define silly_macro为int * silly_macro没有,什么,你想;

该声明不声明什么认为为类型的指针为int,因为宏扩展为:

 为int *没有,什么,你想;

类型说明符为 INT ,并说明符 *不是什么认为。因此,不是有预期的指针类型,但其余标识符不。

而这一切很可能达到99%左右的typedef 和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? 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. Syntactically, it is used in the same place where a storage class specifier like extern or static is 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.

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

enum state {DEAD, ALIVE} stateVariable;

If enum state has previously been introduced the typedef has to be written like this:

typedef enum state State;

otherwise the enum is being redefined, which is an error.

Like other declarations (except function parameter declarations), the typedef declaration can have multiple declarators, separated by a comma. 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. ulong is just a straight alias for that type. 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. In other words ulongptr is an alias for the "pointer to unsigned long" type.

Alias means that ulongptr is not a distinct type from 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.

The aliasing of typedef isn't textual. For instance if user_id_t is a typedef name for the type int, we may not simply do this:

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. The above can be done using the C preprocessor:

#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. 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:

 int * not, what, you, think;

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

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

这篇关于我如何使用typedef,并用C的typedef枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆