在代碼之中使用typedef聲明有助於創建與平臺無關的類型,隱藏C和C++語言中複雜和難以理解的符合類型,創造更爲美觀的代碼。
但是typedef的使用卻有一些很容易混淆的地方,簡單的用法還可以,稍微複雜一些的用法我就搞不懂了。在網上搜了一些資料,
看了看,自己總結了一下。
一、譚浩強版的用typedef定義已有的類型名的別名的步驟如下:
(1)先按定義變量的方法寫出定義體;
(2)將變量名換成新類型名;
(3)在最前面加typedef;
(4)之後就可以用新類型名去定義變量。
二、typedef用法
1、最簡單的用法
如:typedef int myint;
myint sn; //相當於int sn;
是將myint作爲int類型的同義詞。
2、用typedef定義複合類型數組類型的同義詞
如例所示typedef char WORD[20];
WORD w1, w2; //相當於char w1[20]; char w2[20];
則WORD就成了包含20個元素的char數組類型的同義詞。
3、用typedef定義簡單的複合的指針類型同義詞
先看C和C++中指針類型糾結的定義。
char* pa, pb;
char *pc, *pd;
其中pa是char指針類型而pb不是,這多半不符合我們的常規理解方式,如果想要定義兩個char指針,則必須像定義pc和pd那樣;而且*的位置沒有影響。
但是利用typedef我們卻可以定義char*這種複合類型的同義詞。如下所示:
typedef char * chPointer;
chPointer pi, po;這樣pi和po都是char指針類型了。
這裏還有一些需要注意的地方。如下:
有函數int myStrcmp(const char*, const char*) ;
如果定義Typedef char* pStr;而且聲明myStrcmp()如下:
int myStrcmp(const pStr, const pStr),那麼這將是錯誤的。因爲函數原型中的參數是指向char常量的指針,而聲明的卻是指向char的指針常量。
對於這一點我想必須要理解typedef不只是簡單的宏替換。應該從它所表示的意義上去理解。Typedef char* pStr定義的是一個指向char的指針,
所以const pStr中const修飾的是一個指針,也就是說const pStr 表示的是一個char型指針常量。
要解決不一致的問題可以這樣:typedef const char* pStr;這樣聲明函數就變成了:
int myStrcmp(pStr, pStr);
4、typedef用於struct的用法
在舊的C的代碼中聲明struct新對象時,必須要帶上struct,即形式爲:
struct 結構名 對象名,如:
struct POINT
{
int px;
int py;
};
struct POINT pot;
而在C++中,則可以直接寫:結構名 對象名,即:POINT pot;
爲了在C代碼的結構體聲明中少寫一個struct是代碼更爲緊湊和簡約,就有了如下的聲明方法:
typedef struct POINT
{
int px;
int py;
}POINT;
這樣的一段代碼實際上做了兩件事情:
(1)
struct POINT
{
int px;
int py;
};
(2)
typedef struct POINT POINT;
以後就可以這樣聲明struct POINT類型的變量了:POINT pot;顯得簡約一點。
5、typedef隱藏複雜類型的用法
此種用法主要體現在定義函數型的指針上。關鍵點在於根據運算符的結合性,逐步理解其所代表的意義。
(1) 先看C語言中關於函數的聲明
int Function(int ,char);
其對應的函數指針聲明爲:int (*Fp) (int,char);
當進行賦值時可以有以下形式:
Fp = &Function;函數調用時的形式爲:(*Fp)(int, char)。
Fp = Function; 函數調用時的形式爲: Fp(int, char)。
(2)再看C語言中關於數組的聲明
int SN[6];
其對應的數組指針聲明爲int (*pS)[6];注意括號的使用,因爲[]的優先級大於*。
使用方式爲:pS = &SN; int a = (*pS)[0]。
(3)再看以下三個變量聲明
#1 int* (*A[6])(char*,int*);
#2 void (*B[6])(int(*)());
#3 int(*)() (*P)[6];
然後再來分析以上聲明所代表的意義。
#1
int* (*A[6])(char*,int*);
首先看變量名A,因爲[]的結合性大於*,所以A首先是一個數組,然後每個數組元素都是一個指針;再看括號外邊是一個函數的聲明形式,所以A數組中的每一個元素都是指向函數的指針。這種函數返回值爲int*型,參數形式爲(char*,int*)。
用typedef來簡化此種類型聲明:
typedef int* (*pA)(char*, int*);
pA A[6];同int* (*A[6])(char*,int*);
#2
void (*B[6])(int(*)());
類似於#1,B是一個數組,每個元素是一個指針,這個指針指向一個函數,函數的返回值爲void,參數爲int(*)()(也就是一個函數,返回值爲int無參數)。
用typedef來簡化此種類型聲明:
typedef void (*pB)(int (*)() );
pB B[6];同void (*B[6])(int(*)());
當然還可以逐步簡化:
typedef int (*pi) ();簡化指針指向的函數的參數;
typedef void (*pB)(pi);
pB B[6];同void (*B[6])(int(*)())。
#3
int(*)() (*P)[6];
首先P是一個指針,P指向了一個數組,這個數組的每一個元素爲指向函數的指針,指向的函數類型是返回值爲int無參數。
用typedef來簡化此種類型聲明:
typedef int(*pi)();簡化數組的元素定義;
typedef pi (*PP)[6];
PP P;同int(*)() (*P)[6];
(4)2個模式:
type (*)(....) 函數指針 type (*)[] 數組指針
關鍵還在於根據運算符的結合性,理解typedef定義的類型的意義,C語言在很多類似的地方都讓人糾結。