《教學》typedef 知多少?
在C和C++程式語言中,typedef是一個關鍵字。 它用來對一個資料類型起一個新名字
。目的是為了使原始碼更易於閱讀和理解。
很多寫 C/C++ 的人都把 typedef 當成#define
來使用。
誠然,像這樣的定義 typedef unsigned short WORD;
就相當於 #define WORD unsigned
short
但就本義來說,#define 是字串的取代,
例如
#define
WORD Hello!
編譯器不會有任何的抗議就通過的,在程式任何使用到 WORD 的地方
編譯器會忠實的用
Hello! 取代 WORD
由於取代的字串可不限於一行且可代入參數,所以#define 可用於 Macro 的定義如
#define
max(a,b) (((a) > (b)) ? (a) : (b))
回過頭來說typedef主題,從本義來說typedef是
C/C++ 型態的別名。
所以若你想把 #define WORD Hello!
套在 typedef 的身上: typedef Hello! WORD;
那麼編譯器會給你一個難堪錯誤訊息!因為 Hello!
不是一個合法的
型態,你不能為它取型態別名。
typedef看來不怎麼有用是吧!?非也,由於所謂 C/C++
的型態是很廣義的,使用typedef
可以使程式看起來簡潔易懂且不容易出錯。下面是幾個typedef的應用例子:
簡單型態的別名
typedef unsigned char BYTE;
//定義無號單字節的型態
typedef unsigned short WORD; //定義無號雙字節的型態
typedef unsigned
long DWORD; //定義無號四字節的型態
嗯!這三行沒什麼大不了,用#define也可以做
typedef
int MyIntArray [100];
那麼程序中的 MyIntArray ia;
就相當於 int ia[100];
結構型態的別名
typedef struct
StructTag{
int mA;
int mB;
}STRUCTTAG,
*PSTRUCTTAG;
當要建立這個結構的物件時,就可以用別名 STRUCTTAG 和 PSTRUCTTAG,
例如:
STRUCTTAG StructObj;
PSTRUCTTAG pStructObj;
就相當於
struct StructTag StructObj;
struct StructTag
*pStructObj;
函式型態的別名
如果你有一個 library 提供了字串轉整數的函式
int
HexToInt(char *str); //十六進位字串轉整數
int DecToInt(char
*str); //十進位字串轉整數
當你的程式要使用這些函式時,就必需include這些 函式的定義 ,但用typedef會更簡潔:
typedef int ToInt(char
*str); //這行定義了一個需傳入字串(char *)且返回整數(int)的函式型態別名叫 ToInt
ToInt HexToInt,DecToInt;
//宣告HexToInt,DecToInt這兩個函式
現在你的程式可以呼叫HexToInt(...),DecToInt(...)了。
--------------------------------------------------------------------------------------------
假設有兩個分別計算 加 和 減的函數;
int sum(int a, int b)
{
return (a + b);
}
int sub(int a, int b)
{
return (a - b);
}
typedef int (* CalcType) (int a, int b);
int main()
{
int select = -1;
int result;
int a;
int b;
CalcType calculate = sum;
printf("Input two value\n");
// 輸入 兩個數值
scanf("%d %d", &a, &b);
result
= calculate(a, b);
return (0);
}
在Windows,通常是應用程式呼叫API來工作的,但由於某種需求,Windows
API
會反過來呼叫應用程式的函式,這種函式稱之為 callback function。
callback function 對
API 來說只有該傳入那些參數和返回值型態,沒有函式名稱而用函式指標來呼叫(事實上Windows也不可能用程式的函式名稱來呼叫)。這時使用函式型態的別名。
沒有留言:
張貼留言