Typedef

在C和C++程式語言中，codice_1是一個關鍵字。它用來對一個資料型別取一個別名，目的是為了使原始碼更易於閱讀和理解。它通常用於簡化宣告複雜的型別組成的結構 ，但它也常常在各種長度的整數資料型別中看到，例如codice_2和codice_3。語法.codice_1的語法是 : codice_5建立 codice_6 作為 codice_7 的別名 : typedef int Length;建立 codice_8 作為一個指向 "一個擁有兩個 codice_9 當作引數並回傳 codice_7 的函式" 的指標的別名typedef int (*PFI)(char *, char *);使用範例.建立一個具有特別意義的資料型別.codice_1會被用來指定一種資料型別的意義。例如 : 以下示範一個普通的宣告，速度及分數都被宣告為codice_7int current_speed ;int high_score ;void congratulate(int your_score)if (your_score &gt; high_score)透過codice_1來指定新的資料型別的意義:typedef int km_per_hour ;typedef int points ;km_per_hour current_speed ; //"km_per_hour" is synonymous with "int" here,points high_score ; //and thus, the compiler treats our new variables as integers.void congratulate(points your_score) {if (your_score &gt; high_score)前面兩段程式碼運作狀況一樣，但是使用codice_1的第二段程式碼更清楚的表示了兩個變數(score和speed)，雖然資料型別都是codice_7，卻是各自代表不同的意義，且他們的資料並不相容。但請注意，其清楚的表示不同意義只是對於工程師而言，C/C++的編譯器認為兩個變數都是codice_7時，並不會顯示警告或錯誤，如: 以下程式碼，使用宣告為速度的變數作為codice_17函式的引數 :void foo()km_per_hour km100 = 100;congratulate(km100);但是，雖然在上面的程式碼中，編譯器認為"km_per_hour"等於codice_7，但在使用字首 codice_19, codice_20, codice_21時，兩者並不能互換使用。void foo() {unsigned int a; // Okayunsigned km_per_hour b; // Compiler complainslong int c; // Okaylong km_per_hour d; // Compiler complains另一個例子：int coxes;int jaffa;coxes++;if (jaffa == 10)現在來看以下程式碼：typedef int Apple;typedef int Orange;Apple coxes;Orange jaffa;coxes++;if (jaffa == 10)這兩段程式碼都做同樣的一件事。第二個例子使用了 codice_1，使其更易於瞭解將要進行什麼。也就是一個變數包含關於蘋果的資訊，而另一個包含關於橘子的資訊。簡化宣告語法.struct var {int data1;int data2;char data3;此處使用者定義一個資料型別 "codice_23"。像這樣建立一個 "codice_23" 型別的變數，程式碼必須寫為：struct var a;在例子的最末處加入一行語句：typedef struct var newtype;現在要建立型別 "codice_23" 的變數時，程式碼可以寫為：newtype a;這樣就更容易閱讀了，因為不用再為每一個 "var" 型別的變數加上關鍵字 "codice_25"。也可以給陣列使用 codice_1 宣告。typedef BaseType NewType [arrSize];這樣就可以在宣告一個 "codice_30" 型別和 "codice_31" 大小的新陣列時，將程式碼寫為：NewType array;與陣列一起使用.codice_1可以簡單的跟陣列一起使用。例如 :typedef char arrType[6]; // type name: arrType// new type: char[6]arrType *pArr; // same as: char (*pArr)[6];在這裡，codice_33是codice_34的別稱。而codice_35則表示codice_36是一個指向儲存codice_34型別記憶體的指標。與指標一起使用.可以使用typedef來定義一個新的指標型別 :typedef int *intptr; // type name: intptr// new type: int*intptr ptr; // same as: int *ptr在上面那段程式碼中，codice_38是一個 指標型態codice_39的 新的別名。codice_40宣告了一個變數(codice_41)，其資料型別是codice_39。如此一來codice_41就是一個 可以指向一段儲存codice_7資料的記憶體 的指標了。使用codice_1來定義一個新的指標型別有時候會造成一些困惑 :typedef int *intptr;intptr cliff, allen; // both cliff and allen are int* typeintptr cliff2, *allen2; // cliff2 is int* type, but allen2 is int** type// same as: intptr cliff2;// intptr *allen2;在上面的程式碼中,"codice_46"表示宣告兩個變數，其資料型別是codice_39，而codice_48則使codice_49的型別成為codice_50與結構指標一起使用.codice_51可以跟結構體指標一起使用。如下 :struct Node {int data;struct Node *nextptr;使用codice_1可以改寫成如下 :typedef struct Node Node;struct Node {int data;Node *nextptr;在C語言中，可以在一行中宣告複數的變數，不管其是不是指標。不管如何，如果你要宣告指標，必須在每個變數前面加上星號。在下面的程式碼中，工程師可能會以為codice_53是一個指標，這個可能會引起一些錯誤。struct Node *startptr, *endptr, *curptr, *prevptr, errptr, *refptr;如果你用codice_1定義一個codice_55，這可以保證所有的變數都是一個指向一個codice_56的指標。typedef struct Node* NodePtr;NodePtr startptr, endptr, curptr, prevptr, errptr, refptr;與函式指標一起使用.先看看以下這段尚未使用codice_1的程式碼：int do_math(float arg1, int arg2) {return arg2;int call_a_func(int (*call_this)(float, int)) {int output = call_this(5.5, 7);return output;int final_result = call_a_func(&amp;do_math);這段程式碼可以被改寫成如下：typedef int (*MathFunc)(float, int);int do_math(float arg1, int arg2) {return arg2;int call_a_func(MathFunc call_this) {int output = call_this(5.5, 7);return output;int final_result = call_a_func(&amp;do_math);在這裡，codice_58是一個指標，指向一個回傳codice_7並以一個codice_60和一個codice_7作為引數使用的函式。當一個函式被當作引數使用時，如果少了codice_1它可能會變得難以瞭解。以下是codice_63(來自FreeBSD)的函式原型：void (*signal(int sig, void (*func)(int)))(int);上面宣告的函式相當的神秘，因為它沒有清楚的顯示它以什麼函式當作引數，或回傳了什麼資料型別。一個初心者工程師甚至可能以為它接收一個codice_7作為引數，並不回傳任何東西。但它其實接收了一個codice_7和一個codice_66作為引數，並回傳了一個codice_66。它可以被改寫成以下程式碼：typedef void (*sighandler_t)(int);sighandler_t signal(int sig, sighandler_t func);用來型別轉換.codice_1同時可以用來型別轉換。例如：typedef int (*funcptr)(double); // pointer to function taking a double returning intfuncptr x = (funcptr) NULL; // C or C++funcptr y = funcptr(NULL); // C++ onlyfuncptr z = static_cast(NULL); // C++ only左側，codice_69用來宣告變數；右側，codice_69則用來轉換值的型態。如果少了codice_1，替換使用宣告語法和型別轉換語法是幾乎不能做到的。例如：void *p = NULL;int (*x)(double) = (int (*)(double)) p; // This is legalint (*)(double) y = (int (*)(double)) p; // Left-hand side is not legalint (*z)(double) = (int (*p)(double)); // Right-hand side is not legal