问题描述
考虑:
的#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枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!