一、typedef用法:
①
定義一種類型的別名,而不只是簡單的宏替換。可用作同時聲明指標類型的多個對象。陷阱:typedef char* TCHAR;
TCHAR pa, pb;//pa和pb都是指標類型。#define不能達到此效果。
陷阱:typedef char* PSTR;
int mystrcmp(const PSTR, const PSTR);const PSTR相當於char*嗎?不是的,它實際上相當於char*
const。const給了整個指標以常量性。要想定義一個常量指標,需:
typedef const char* cpstr;
②
定義與平台無關的類型。如定義一個叫REAL的浮點類型,
在平台1上實現為:typedef long double REAL;在平台2上實現為:typedef double REAL;
在平台3上實現為:typedef float REAL;即當跨平台時,只需修改typedef本身。
③
為複雜的聲明定義一個新的簡單的別名。方法是:在原來的聲明裡逐步用別名替換一部分複雜聲明,如此迴圈,把帶變數名的部分留到最後替換,得到的就是原聲明的簡化版。如:
Ø 原聲明:int *(*a[5])(int, char);
變數名為a,直接用一個新別名pFun替換a就可以了:
typedef int*(*pFun)(int, char);原聲明的最簡化版:pFun a[5];
Ø 原聲明:void (*b[10]) (void (*)());
變數名為b,先替換右邊部分括弧裡的,pFunParam為別名一:
typedef void (*pFunParam)();
再替換左邊的變數b,pFunx為別名二:
typedef void (*pFunx)(pFunParam);
原聲明的最簡化版:pFunx b[10];
Ø 原聲明:doube(*)() (*e)[9];
變數名為e,先替換左邊部分,pFuny為別名一:
typedef double(*pFuny)();
再替換右邊的變數e,pFunParamy為別名二
typedef pFuny (*pFunParamy)[9];
原聲明的最簡化版:pFunParamy e;
理解複雜聲明可用的“右左法則”:
從變數名看起,先往右,再往左,碰到一個圓括弧就調轉閱讀的方向;括弧內分析完就跳出括弧,還是按先右後左的順序,如此迴圈,直到整個聲明分析完。舉例:
int (*func)(int *p);
首先找到變數名func,外面有一對圓括弧,而且左邊是一個*號,這說明func是一個指標;然後跳出這個圓括弧,先看右邊,又遇到圓括弧,這說明(*func)是一個函數,所以func是一個指向這類函數的指標,即函數指標,這類函數具有int*類型的形參,傳回值類型是int。
int (*func[5])(int *);
func右邊是一個[]運算子,說明func是具有5個元素的數組;func的左邊有一個*,說明func的元素是指標。跳出這個括弧,看右邊,又遇到圓括弧,說明func數組的元素是函數類型的指標,它指向的函數具有int*類型的形參,傳回值類型為int。
常見用法舉例:
Ø 數群組類型定義:typedef int arr[2];arr相當於int[2]定義。arr a;相當於int
a[2];
Ø 函數指標:typedef int (*func)(void);func等價於int(*)(void)。func pf等價於int
(*pf)(void);
二、#define:預先處理指令。在先行編譯(即預先處理)階段進行簡單替換,不作正確性檢查。用途:
①
定義宏。
②
標頭檔保護符。(本質同③)
③
做一些條件判斷。
三、常量指標和指標常量:const在*前為常(首字母為C)量指標(首字母為Z),即const在*前為正序(CZ);const在*後為指(首字母為Z)針常量(首字母為C),即const在*後為倒序。常量指標-----所指向的地址可變,地址儲存的內容不可變。指標常量-----所指向地址不可變。