[英]How do I use typedef and typedef enum in C?
考慮:
#define MAXROW 20
#define MAXCOL 60
typedef State Grid[MAXROW+2] [MAXCOL+2]
typedef enum state {DEAD,ALIVE} State
如何在 C 中使用typedef
和typedef enum
? 這部分代碼的作用是什么?
typedef enum state {DEAD,ALIVE} State;
| | | | | |^ terminating semicolon, required!
| | | type specifier | | |
| | | | ^^^^^ declarator (simple name)
| | | |
| | ^^^^^^^^^^^^^^^^^^^^^^^
| |
^^^^^^^-- storage class specifier (in this case typedef)
typedef
關鍵字是偽存儲類說明符。 從語法上講,它用於使用extern
或static
等存儲類說明符的相同位置。 它與存儲沒有任何關系。 這意味着聲明不會引入命名對象的存在,而是引入了類型別名的名稱。
在上述聲明之后, 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
引入了兩個類型名稱ulong
和ulongptr
,它們基於說明符限定符列表中給出的unsigned long
類型。 ulong
只是該類型的直接別名。 ulongptr
被聲明為指向unsigned long
的指針,這要歸功於*
語法,該語法在這個角色中是一種類型構造運算符,故意模仿表達式中使用的指針解除引用的一元*
。 換句話說, ulongptr
是“指向unsigned long
”類型的別名。
別名意味着ulongptr
不是 unsigned long *
的獨特類型 。 這是有效的代碼,無需診斷:
unsigned long *p = 0;
ulongptr q = p;
變量q
和p
具有完全相同的類型。
typedef
的別名不是文本的。 例如,如果user_id_t
是int
類型的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;
這個聲明沒有聲明what
, you
並think
是“指向int的類型”,因為宏擴展是:
int * not, what, you, think;
類型說明符是int
,聲明符是*not
, what
, you
和think
。 所以not
預期的指針類型,但其余的標識符沒有。
這可能是關於typedef
和C語言類型別名的99%。
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
}
}
typedef只是一個別名-
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.