簡體   English   中英

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

[英]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 中使用typedeftypedef enum 這部分代碼的作用是什么?

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

typedef關鍵字是偽存儲類說明符。 從語法上講,它用於使用externstatic等存儲類說明符的相同位置。 它與存儲沒有任何關系。 這意味着聲明不會引入命名對象的存在,而是引入了類型別名的名稱。

在上述聲明之后, 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預期的指針類型,但其余的標識符沒有。

這可能是關於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只是一個別名-

  • “typedef 是編程語言 C 和 C++ 中的保留關鍵字。它用於為另一種數據類型創建附加名稱別名),但不創建新類型”( Wiki

  • “typedef 聲明提供了一種將標識符聲明為類型別名的方法,用於替換可能復雜的類型名稱”( cppreference

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM