C++?typedef常見用法詳解
typedef的4種常見用法:
- 給已定義的變量類型起個(gè)別名
- 定義函數(shù)指針類型
- 定義數(shù)組指針類型
- 為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名
總結(jié)一句話:“加不加typedef,類型是一樣的",這句話可以這樣理解:
沒加typedef之前如果是個(gè)數(shù)組,那么加typedef之后就是數(shù)組類型;
沒加typedef之前如果是個(gè)函數(shù)指針,那么加typedef之后就是函數(shù)指針類型;
沒加typedef之前如果是個(gè)指針數(shù)組,那么加typedef之后就是指針數(shù)組類型。
typedef char TA[5];//定義數(shù)組類型 typedef char *TB[5];//定義指針數(shù)組類型,TB定義的變量為含5個(gè)char*指針元素的數(shù)組(指針數(shù)組類型) typedef char *(TC[5]);//指針數(shù)組類型,因?yàn)閇]的結(jié)合優(yōu)先級(jí)最高,所以加不加()沒啥區(qū)別,TC等價(jià)于TB typedef char (*TD)[5];//數(shù)組指針類型,TD指向一個(gè)5容量的char數(shù)組
后文簡(jiǎn)單介紹下指針數(shù)組和數(shù)組指針
typedef的4種用法詳解
1、給已定義的變量類型起個(gè)別名
(1)typedef unsigned char uin8_t; //uint8_t就是unsigned char的別名,這是最基礎(chǔ)的用法;
(2)結(jié)構(gòu)體用法——作用是給struct __person起了個(gè)別名person_t,這種這種用法也很基礎(chǔ);
struct __person { char name[20]; uint8_t age; uint8_t height; } typedef __person person_t; //以上兩段代碼也可合并為一段,如下: typedef struct __person { char name[20]; uint8_t age; uint8_t height; }person_t;
2、定義函數(shù)指針類型
首先來看一下如何定義函數(shù)指針變量,然后再看如何定義函數(shù)指針類型。
(1)定義函數(shù)指針變量
定義了一個(gè)函數(shù)指針變量pFunc,它可以指向這樣的函數(shù):返回值為int,形參為char*、int:
int (*pFunc)(char *frame, int len);
定義了5個(gè)函數(shù)指針變量:pFunc[0]、pFunc[1]···,它們都可以指向這樣的函數(shù):返回值為int*,形參為int:
int *(*pFunc[5])(int len);
(2)定義函數(shù)指針類型
定義函數(shù)指針類型,必須使用typedef,方法就是,在“定義函數(shù)指針變量”前加上typedef。
typedef int (*pFunc_t)(char *frame, int len);//定義了一個(gè)類型pFunc_t
舉例:
typedef int (*pFunc_t)(char *frame, int len);//定義了一個(gè)類型pFunc_t int read_voltage(char *data, int len) { int voltage = 0; ···//其他功能代碼 return voltage; } int main(void) { pFunc_t pHandler = read_voltage;//使用類型pFunc_t來定義函數(shù)指針變量 ···//其他功能代碼 }
3、定義數(shù)組指針類型
這個(gè)問題還是分兩步,先看如何定義數(shù)組指針變量,再看如何定義數(shù)組指針類型。
(1)定義數(shù)組指針變量
int(*pArr)[5];//定義了一個(gè)數(shù)組指針變量pArr,pArr可以指向一個(gè)int [5]的一維數(shù)組
char(*pArr)[4][5];///定義了一個(gè)數(shù)組指針變量pArr,pArr可以指向一個(gè)char[4][5]的二維數(shù)組
char(*pArr)[4][5];///定義了一個(gè)數(shù)組指針變量pArr,pArr可以指向一個(gè)char[4][5]的二維數(shù)組
int(*pArr)[5];//pArr是一個(gè)指向含5個(gè)int元素的一維數(shù)組的指針變量 int a[5] = {1,2,3,4,5}; int b[6] = {1,2,3,4,5,6}; pArr = &a;//完全合法,無警告 pArr = a;//發(fā)生編譯警告,賦值時(shí)類型不匹配:a的類型為int(*),而pArr的類型為int(*)[5] pArr = &a[0];//發(fā)生編譯警告,賦值時(shí)類型不匹配:a的類型為int(*),而pArr的類型為int(*)[5] pArr = &b;//發(fā)生編譯警告,賦值時(shí)類型不匹配:&b的類型為int(*)[6],而pArr的類型為int(*)[5] pArr = (int(*)[5])&b;//類型強(qiáng)制轉(zhuǎn)換為int(*)[5],完全合法,無警告
上面這個(gè)例子中,使用類型轉(zhuǎn)換時(shí),代碼的樣式略顯復(fù)雜,試想,我們?nèi)绻麖?qiáng)轉(zhuǎn)為一個(gè)結(jié)構(gòu)體數(shù)組的指針,那這個(gè)強(qiáng)轉(zhuǎn)的括號(hào)里的內(nèi)容得多長(zhǎng)!這就直接影響了代碼的可讀性,因此,強(qiáng)轉(zhuǎn)后的類型應(yīng)該定義出來。
(2)定義數(shù)組指針類型
如同上面定義函數(shù)指針類型的方法,直接在前面加typedef即可,例如:
typedef int (*pArr_t)[5];//定義了一個(gè)指針類型pArr_t,該類型的指針可以指向含5個(gè)int元素的數(shù)組
typedef int(*pArr_t)[5];//定義一個(gè)指針類型,該類型的指針可以指向含5個(gè)int元素的一維數(shù)組 int main(void) { int a[5] = {1,2,3,4,5}; int b[6] = {1,2,3,4,5,6}; pArr_t pA;//定義數(shù)組指針變量pA pA= &a;//完全合法,無警告 pA= (pArr_t)&b;//類型強(qiáng)制轉(zhuǎn)換為pArr_t,完全合法,無警告 }
(3)定義數(shù)組類型
如果我們想聲明一個(gè)含5個(gè)int元素的一維數(shù)組,一般會(huì)這么寫:int a[5];
如果我們想聲明多個(gè)含5個(gè)int元素的一維數(shù)組,一般會(huì)這么寫:int a1[5], a2[5], a3[5]···,或者 a[N][5]
可見,對(duì)于定義多個(gè)一維數(shù)組,寫起來略顯復(fù)雜,這時(shí),我們就應(yīng)該把數(shù)組定義為一個(gè)類型,例如:
typedef int arr_t[5];//定義了一個(gè)數(shù)組類型arr_t,該類型的變量是個(gè)數(shù)組。
typedef int arr_t[5]; int main(void) { arr_t d; //d是個(gè)數(shù)組,這一行等價(jià)于: int d[5]; arr_t b1, b2, b3;//b1, b2, b3都是數(shù)組 d[0] = 1; d[1] = 2; d[4] = 134; d[5] = 253;//編譯警告:下標(biāo)越界 }
4、為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名
為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名。方法是:在原來的聲明里逐步用別名替換一部分復(fù)雜聲明,如此循環(huán),把帶變量名的部分留到最后替換,得到的就是原聲明的最簡(jiǎn)化版。舉例:
int *(*a[5])(int, char*);//原聲明 typedef int *(*pFun)(int, char*); //變量名為a,直接用一個(gè)新別名pFun替換a就可以了 pFun a[5];//原聲明的最簡(jiǎn)化版
void (*b[10]) (void (*)());//原聲明 typedef void (*pFunParam)();//變量名為b,先替換右邊部分括號(hào)里的,pFunParam為別名一 typedef void (*pFunx)(pFunParam);//再替換左邊的變量b,pFunx為別名二 pFunx b[10];//原聲明的最簡(jiǎn)化版
兩大陷阱
陷阱一:記住,typedef是定義了一種類型的新別名,不同于宏,它不是簡(jiǎn)單的字符串替換。
陷阱二:typedef在語法上是一個(gè)存儲(chǔ)類的關(guān)鍵字(如auto、extern、mutable、static、register等一樣),雖然它并不真正影響對(duì)象的存儲(chǔ)特性。
typedef 與 #define的區(qū)別
案例一:
通常講,typedef要比#define要好,特別是在有指針的場(chǎng)合。請(qǐng)看例子:
typedef char *pStr1; #define pStr2 char *; pStr1 s1, s2; pStr2 s3, s4;
在上述的變量定義中,s1、s2、s3都被定義為char *,而s4則定義成了char,不是我們所預(yù)期的指針變量,根本原因就在于#define只是簡(jiǎn)單的字符串替換而typedef則是為一個(gè)類型起新名字。
案例二:
下面的代碼中編譯器會(huì)報(bào)一個(gè)錯(cuò)誤,你知道是哪個(gè)語句錯(cuò)了嗎?
typedef char * pStr; char str[4] = "abc"; const char *p1 = str; const pStr p2 = str; p1++; p2++;
是p2++出錯(cuò)了。這個(gè)問題再一次提醒我們:typedef和#define不同,它不是簡(jiǎn)單的文本替換。上述代碼中const pStr p2并不等于const char * p2。const pStr p2和const long x本質(zhì)上沒有區(qū)別,都是對(duì)變量進(jìn)行只讀限制,只不過此處變量p2的數(shù)據(jù)類型是我們自己定義的而不是系統(tǒng)固有類型而已。因此,const pStr p2的含義是:限定數(shù)據(jù)類型為pStr 的變量p2為只讀,因此p2++錯(cuò)誤。
對(duì)于指針數(shù)組和數(shù)組指針的概念,相信很多人經(jīng)常會(huì)感到迷惑,見到二者一時(shí)不能分辨究竟對(duì)應(yīng)哪一個(gè)才是對(duì)的。接下來我們來分析一下二者區(qū)別。
我們來看一下這個(gè)示例代碼:
int *ptr1[10]; int (*ptr2)[10];
對(duì)于上述代碼語句,你是否能分清哪一句代碼聲明的是指針數(shù)組,而哪一句代碼聲明的又是數(shù)組指針呢?
答案是第一行代碼聲明的ptr1是一個(gè)指針數(shù)組,數(shù)組名為 ptr1,而“int*”修飾的是數(shù)組的內(nèi)容,該數(shù)組包含 5 個(gè) 指向 int 類型 數(shù)據(jù)的指針。第二行代碼聲明的ptr2則是一個(gè) 數(shù)組的指針 ,指針變量名為 ptr2,而 int 修飾的是數(shù)組的內(nèi)容,即數(shù)組的每個(gè)元素。即ptr2 是一個(gè)指針,它指向一個(gè)包含 5 個(gè) int 類型數(shù)據(jù)的數(shù)組。
這里其實(shí)可以首先看*能否與前面的類型結(jié)合,能的話,內(nèi)容就是結(jié)合后的內(nèi)容。
到此這篇關(guān)于C++ typedef用法詳解的文章就介紹到這了,更多相關(guān)C++ typedef用法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言實(shí)現(xiàn)簡(jiǎn)單的圖書管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡(jiǎn)單的圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C++用函數(shù)對(duì)算法性能進(jìn)行測(cè)試
算法無處不在,算法是程序的靈魂,而數(shù)據(jù)結(jié)構(gòu)則是程序的骨架,二者共同構(gòu)成了程序,那么如何評(píng)估算法的性能呢?理論上可以通過計(jì)算時(shí)間復(fù)雜度的方法來評(píng)估,但這是理性的認(rèn)識(shí),我們還有一種直觀的評(píng)估方法,那就是程序執(zhí)行的時(shí)間2022-08-08C++中四種對(duì)象生存期和作用域以及static的用法總結(jié)分析
以下是對(duì)C++中四種對(duì)象生存期和作用域以及static的用法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下2013-09-09QT5交叉編譯入門級(jí)教程(arm64、mips64)
交叉編譯就是在當(dāng)前系統(tǒng)平臺(tái)上,開發(fā)編譯運(yùn)行于其它平臺(tái)的程序,比如本文硬件環(huán)境是x86平臺(tái),但是編譯出來的程序是在arm64架構(gòu)、mips64等架構(gòu)上運(yùn)行,本文給大家分享QT5交叉編譯入門級(jí)教程(arm64、mips64),感興趣的朋友一起看看吧2023-11-11C語言實(shí)現(xiàn)簡(jiǎn)易訂餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡(jiǎn)易訂餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06對(duì)for循環(huán)中表達(dá)式和循環(huán)體的執(zhí)行順序詳解
今天小編就為大家分享一篇對(duì)for循環(huán)中表達(dá)式和循環(huán)體的執(zhí)行順序詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06