一、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在*後為倒序。常量指針-----所指向的位址可變,位址存儲的内容不可變。指針常量-----所指向位址不可變。