日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言再学习 -- 关键字typedef

發(fā)布時(shí)間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言再学习 -- 关键字typedef 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

參看:C語言再學(xué)習(xí) -- 結(jié)構(gòu)和其他數(shù)據(jù)形式

參看:C語言再學(xué)習(xí) -- 關(guān)鍵字struct(轉(zhuǎn))

參看:常見typedef 用法

參看:關(guān)于typedef的用法總結(jié)

一、typedef 介紹

typedef為C語言的關(guān)鍵字,作用是為一種數(shù)據(jù)類型定義一個(gè)新名字。比如人們常常使用 typedef 來編寫更美觀和可讀的代碼。所謂美觀,意指 tepedef 能隱藏笨拙的語法構(gòu)造以及平臺(tái)相關(guān)的數(shù)據(jù)類型,從而增強(qiáng)可移植性以及未來的可維護(hù)性。

這里的數(shù)據(jù)類型包括內(nèi)部數(shù)據(jù)類型(int,char等)和自定義的數(shù)據(jù)類型(struct等)。 在編程中使用typedef目的一般有兩個(gè),一個(gè)是給變量一個(gè)易記且意義明確的新名字,另一個(gè)是簡(jiǎn)化一些比較復(fù)雜的類型聲明。

typedef 使用方法如下:

typedef existing_type new_type_name; 注意:typedef 并不創(chuàng)建新的類型。它僅僅為現(xiàn)有類型添加一個(gè)同義字。

typedef的簡(jiǎn)單應(yīng)用:

typedef unsigned char BYTE; BYTE b1, b2;

在這個(gè)類型定義之后,標(biāo)識(shí)符 BYTE 可作為類型 unsigned char 的縮寫。該定義的作用域取決于 typedef 語句所在的位置。如果定義是在一個(gè)函數(shù)內(nèi)部,它的作用域是局部的,限定在那個(gè)函數(shù)里。如果定義是在函數(shù)外部,它將具有全局作用域。

通常,這些定義使用大寫字母,以提醒用戶這個(gè)類型名稱實(shí)際上是一個(gè)符號(hào)縮寫。不過,您也可以使用小寫字母。


二、typedef 用法總結(jié)

1、typedef 與 define 區(qū)別

首先你要了解 typedef 和 define 的區(qū)別,宏定義只是簡(jiǎn)單的字符串代換,是在預(yù)處理完成的,而typedef是在編譯時(shí)處理的,它不是作簡(jiǎn)單的代換,而是對(duì)類型說明符重新命名。被命名的標(biāo)識(shí)符具有類型定義說明的功能。

請(qǐng)看下面的例子:

#define P1 int *

typedef (int *) P2

從形式上看這兩者相似,但在實(shí)際使用中卻不相同。

下面用P1、P2說明變量時(shí)就可以看出它們的區(qū)別:

P1 a, b; ?在宏代換后變成: int *a, b; ?表示 a 是指向整型的指針變量,而 b 是整型變量。

P2 a, b; ?表示a,b都是指向整型的指針變量。因?yàn)镻IN2是一個(gè)類型說明符。

由這個(gè)例子可見,宏定義雖然也可表示數(shù)據(jù)類型, 但畢竟是作字符代換。在使用時(shí)要分外小心,以避出錯(cuò)。


總結(jié),typedef和#define的不同之處:

1、與#define不同,typedef 給出的符號(hào)名稱僅限于對(duì)類型,而不是對(duì)值。

2、typedef 的解釋由編譯器,而不是是處理器執(zhí)行。

3、雖然它的范圍有限,但在其受限范圍內(nèi),typedef 比 #define 更靈活。


2、常規(guī)變量類型定義

typedef 聲明可用來表示一個(gè)變量的含義。

例如:typedef unsigned char uchar
描述:uchar等價(jià)于unsigned char類型定義
? ? ? ? ? ?uchar c聲明等于unsigned char c聲明


3、數(shù)組類型定義

例如: typedef int array[2];
描述: array等價(jià)于 int [2]定義;
? ? ? ? ? ? array a聲明等價(jià)于int a[2]聲明

擴(kuò)展: typedef int array[M][N];
描述: array等價(jià)于 int [M][N]定義;
? ? ? ? ? ? array a聲明等價(jià)于int a[M][N]聲明


4、指針類型定義

例如: typedef int *pointer;
描述: pointer等價(jià)于 int *定義;
? ? ? ? ? ? pointer p聲明等價(jià)于int *p聲明

例如: typedef int *pointer[M];
描述: pointer等價(jià)于 int *[M]定義;
? ? ? ? ? ? pointer p聲明等價(jià)于int *p[M]聲明


5、函數(shù)地址說明
描述: C把函數(shù)名字當(dāng)做函數(shù)的首地址來對(duì)待,我們可以使用最簡(jiǎn)單的方法得到函數(shù)地址
例如: 函數(shù):int func(void);
? ? ? ? ? ? unsigned long funcAddr=(unsigned long)func;
? ? ? ? ? ? funcAddr的值是func函數(shù)的首地址

6、函數(shù)聲明
例如: typedef int func(void); ?
? ? ? ? ? ? func等價(jià)于 int (void)類型函數(shù)
描述1: func f聲明等價(jià)于 int f(void)聲明,用于文件的函數(shù)聲明
描述2: func *pf聲明等價(jià)于 int (*pf)(void)聲明,用于函數(shù)指針的聲明,見下一條

7、函數(shù)指針
例如: typedef int (*func)(void)
描述: func等價(jià)于int (*)(void)類型
? ? ? ? ? ? func pf等價(jià)于int (*pf)(void)聲明,pf是一個(gè)函數(shù)指針變量

8、識(shí)別typedef的方法:
a).第一步。使用已知的類型定義替代 typdef 后面的名稱,直到只剩下一個(gè)名字不識(shí)別為正確
? ? 如typedef u32 ? (*func)(u8);
? ? 從上面的定義中找到 typedef __u32 ?u32; typedef __u8 u8
? ? 繼續(xù)找到 typedef unsigned int __u32; typedef unsigned char __u8;
? ? 替代位置名稱 typedef unsigned int ?(*func)(void);
? ? 現(xiàn)在只有func屬于未知
b).第二步.未知名字為定義類型,類型為取出名稱和 typedef 的所有部分,如上為
? ? func等價(jià)于unsigned unsigned ?int ?(*)(unsigned ?char);
c).第三部.定義一個(gè)變量時(shí),變量類型等價(jià)于把變量替代未知名字的位置所得到的類型
? ? func f等價(jià)于unsigned unsigned int ?(*f)(unsigned char)


9、結(jié)構(gòu)體定義

結(jié)構(gòu)體的一般定義形式為:

標(biāo)簽(tag)字段允許為成員列表提供一個(gè)名字,這樣它就可以在后續(xù)的聲明中使用。標(biāo)簽允許多個(gè)聲明使用同一個(gè)成員列表,并且創(chuàng)建同一種類型的結(jié)構(gòu)。

[cpp]?view plaincopy
  • struct 標(biāo)簽{????
  • ?????類型名1 成員名1;??
  • ?????類型名2 成員名2;??
  • ????……??
  • ?????類型名n 成員名n;   ??
  • ?}結(jié)構(gòu)體變量; ?
  • 如果?標(biāo)簽?存在,結(jié)構(gòu)體變量?不存在,定義如下: [cpp]?view plaincopy
  • struct?Student{??
  • ????char?name[20];//姓名??
  • ????int?age;//年齡??
  • ????float?height;//身高??
  • };??
  • ??
  • struct?Student?stu???//Student?為標(biāo)簽??stu?為結(jié)構(gòu)體變量??
  • 如果?結(jié)構(gòu)體變量?存在,?標(biāo)簽?可有可無,定義如下: [cpp]?view plaincopy
  • struct?Student{??//Student?可有可無??
  • ????char?name[20];//姓名??
  • ????int?age;//年齡??
  • ????float?height;//身高??
  • }stu; ?
  • 使用typedef起別名,標(biāo)簽?可有可無,結(jié)構(gòu)體變量?位置變?yōu)樵?類型名 [cpp]?view plaincopy
  • typedef?struct?Student{?//Student?可有可無??
  • ????char?name[20];//姓名??
  • ????int?age;//年齡??
  • ????float?height;//身高??
  • }Stu;?//Stu?為類型名??
  • ??
  • Stu?stu;?//Stu?為類型名,stu?為結(jié)構(gòu)體變量??
  • 注意,字符串初始化不能直接賦值,需要使用 strcpy 函數(shù) [cpp]?view plaincopy
  • #include?<stdio.h>????
  • #include?<string.h>????
  • ????
  • typedef?struct?????
  • {????
  • ????int?n;????
  • ????float?m;????
  • ????char?name[20];????
  • }Ptr;????
  • ????
  • int?main?(void)????
  • {????
  • ????Ptr?p;????
  • ????//Ptr?p?=?{11,?12.9,?"hello"};?????
  • ????strcpy?(p.name,?"hello");??//注意字符串不能直接賦值????
  • ????p.n?=?11;????
  • ????p.m?=?12.9;????
  • ????printf?("n?=?%d,?name?=?%s,?m?=?%g\n",?p.n,?p.name,?p.m);????
  • ????return?0;????
  • }????
  • 輸出結(jié)果:????
  • n?=?11,?name?=?hello,?m?=?12.9 ? ?

  • 10、結(jié)構(gòu)體指針

    struct Node {int data;struct Node *nextptr; };
    使用 typede 上面的代碼可以改寫為如下:

    typedef struct Node pNode; struct Node {int data;pNode *nextptr; };

    或者

    typedef struct Node{int data;struct Node *nextptr; }pNode;

    三、typedef 用途

    用途一:與#define的區(qū)別

    typedef 行為有點(diǎn)像 #define 宏,用其實(shí)際類型替代同義字。不同點(diǎn)是 typedef 在編譯時(shí)被解釋,

    因此讓編譯器來應(yīng)付超越預(yù)處理器能力的文本替換。


    ?用途二:減少錯(cuò)誤

    定義一種類型的別名,而不只是簡(jiǎn)單的宏替換。可以用作同時(shí)聲明指針型的多個(gè)對(duì)象。比如:

    [cpp]?view plaincopy print?
  • char*?pa,?pb;?//?這多數(shù)不符合我們的意圖,它只聲明了一個(gè)指向字符變量的指針,??
  • //?和一個(gè)字符變量;??
  • 以下則可行:

    [cpp]?view plaincopy print?
  • typedef?char*?PCHAR;??
  • PCHAR?pa,?pb;????
  • 這種用法很有用,特別是char* pa, pb的定義,初學(xué)者往往認(rèn)為是定義了兩個(gè)字符型指針,其實(shí)不是,而用typedef char* PCHAR就不會(huì)出現(xiàn)這樣的問題,減少了錯(cuò)誤的發(fā)生。


    用途三: ? ?直觀簡(jiǎn)潔

    用在舊的C代碼中,幫助struct。以前的代碼中,聲明struct新對(duì)象時(shí),必須要帶上struct,即形式為: struct 結(jié)構(gòu)名對(duì)象名,如:

    [cpp]?view plaincopy print?
  • struct?tagPOINT1??
  • ?{??
  • ????int?x;??
  • ????int?y;???
  • };??
  • struct?tagPOINT1?p1;??
  • 而在C++中,則可以直接寫:結(jié)構(gòu)名對(duì)象名,即:tagPOINT1 p1;

    [cpp]?view plaincopy print?
  • typedef?struct?tagPOINT??
  • {??
  • ????int?x;??
  • ????int?y;??
  • }POINT;??
  • POINT p1; // 這樣就比原來的方式少寫了一個(gè)struct,比較省事,尤其在大量使用的時(shí)候,或許,在C++中,typedef的這種用途二不是很大,但是理解了它,對(duì)掌握以前的舊代碼還是有幫助的,畢竟我們?cè)陧?xiàng)目中有可能會(huì)遇到較早些年代遺留下來的代碼。


    用途四:平臺(tái)無關(guān)性

    用typedef來定義與平臺(tái)無關(guān)的類型。

    typedef 有另外一個(gè)重要的用途,那就是定義機(jī)器無關(guān)的類型,例如,你可以定義一個(gè)叫 REAL 的浮點(diǎn)類型,在目標(biāo)機(jī)器上它可以獲得最高的精度:? [cpp]?view plaincopy print?
  • typedef?long?double?REAL;???
  • 在不支持 long double 的機(jī)器上,該 typedef 看起來會(huì)是下面這樣:? [cpp]?view plaincopy print?
  • typedef?double?REAL;???
  • 并且,在連 double 都不支持的機(jī)器上,該 typedef 看起來會(huì)是這樣: [cpp]?view plaincopy print?
  • typedef?float?REAL;???
  • 也就是說,當(dāng)跨平臺(tái)時(shí),只要改下 typedef 本身就行,不用對(duì)其他源碼做任何修改。

    標(biāo)準(zhǔn)庫就廣泛使用了這個(gè)技巧,比如size_t。另外,因?yàn)閠ypedef是定義了一種類型的新別名,不是簡(jiǎn)單的字符串替換,所以它比宏來得穩(wěn)健。


    用途五:掩飾復(fù)合類型

    typedef 還可以掩飾復(fù)合類型,如指針和數(shù)組。?

    例如,你不用像下面這樣重復(fù)定義有 81 個(gè)字符元素的數(shù)組:? [cpp]?view plaincopy print?
  • char?line[81];??
  • char?text[81];???
  • 定義一個(gè) typedef,每當(dāng)要用到相同類型和大小的數(shù)組時(shí),可以這樣:? [cpp]?view plaincopy print?
  • typedef?char?Line[81];???
  • 此時(shí)Line類型即代表了具有81個(gè)元素的字符數(shù)組,使用方法如下:? [cpp]?view plaincopy print?
  • Line?text,?secondline;??
  • getline(text);???
  • 同樣,可以象下面這樣隱藏指針語法:? [cpp]?view plaincopy print?
  • typedef?char?*?pstr;??
  • int?mystrcmp(pstr,?pstr);??
  • 這里將帶我們到達(dá)第一個(gè) typedef 陷阱。標(biāo)準(zhǔn)函數(shù) strcmp()有兩個(gè)‘ const char *'類型的參數(shù)。因此,它可能會(huì)誤導(dǎo)人們象下面這樣聲明 mystrcmp():? [cpp]?view plaincopy print?
  • int?mystrcmp(const?pstr,?const?pstr);???
  • 用GNU的gcc和g++編譯器,是會(huì)出現(xiàn)警告的,按照順序,‘const pstr'被解釋為‘char* const‘(一個(gè)指向 char 的指針常量),兩者表達(dá)的并非同一意思。為了得到正確的類型,應(yīng)當(dāng)如下聲明:? [cpp]?view plaincopy print?
  • typedef?const?char*?pstr;??

  • 用途六:代碼簡(jiǎn)化

    代碼簡(jiǎn)化。為復(fù)雜的聲明定義一個(gè)新的簡(jiǎn)單的別名。方法是:在原來的聲明里逐步用別名替換一部分復(fù)雜聲明,如此循環(huán),把帶變量名的部分留到最后替換,得到的就是原聲明的最簡(jiǎn)化版。舉例:?

    ?原聲明:

    [cpp]?view plaincopy print?
  • void?(*b[10])?(void?(*)());??
  • 變量名為b,先替換右邊部分括號(hào)里的,pFunParam為別名

    [cpp]?view plaincopy print?
  • typedef?void?(*pFunParam)();??
  • 再替換左邊的變量b,pFunx為別名二:

    [cpp]?view plaincopy print?
  • typedef?void?(*pFunx)(pFunParam);??
  • 原聲明的最簡(jiǎn)化版:

    [cpp]?view plaincopy print?
  • pFunx?b[10];??
  • 原聲明:

    [cpp]?view plaincopy print?
  • doube(*)()?(*e)[9];??
  • 變量名為e,先替換左邊部分,pFuny為別名一:

    [cpp]?view plaincopy print?
  • typedef?double(*pFuny)();??
  • 再替換右邊的變量e,pFunParamy為別名二

    [cpp]?view plaincopy print?
  • typedef?pFuny?(*pFunParamy)[9];??
  • 原聲明的最簡(jiǎn)化版:

    [cpp]?view plaincopy print?
  • pFunParamy?e;??
  • 理解復(fù)雜聲明可用的“右左法則”:從變量名看起,先往右,再往左,碰到一個(gè)圓括號(hào)就調(diào)轉(zhuǎn)閱讀的方向;括號(hào)內(nèi)分析完就跳出括號(hào),還是按先右后左的順序,如此循環(huán),直到整個(gè)聲明分析完。舉例:

    [cpp]?view plaincopy print?
  • int?(*func)(int?*p);??
  • 首先找到變量名func,外面有一對(duì)圓括號(hào),而且左邊是一個(gè)*號(hào),這說明func是一個(gè)指針;然后跳出這個(gè)圓括號(hào),先看右邊,又遇到圓括號(hào),這說明(*func)是一個(gè)函數(shù),所以func是一個(gè)指向這類函數(shù)的指針,即函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值類型是int。

    [cpp]?view plaincopy print?
  • int?(*func[5])(int?*);??
  • func右邊是一個(gè)[]運(yùn)算符,說明func是具有5個(gè)元素的數(shù)組;func的左邊有一個(gè)*,說明func的元素是指針(注意這里的*不是修飾func,而是修飾func[5]的,原因是[]運(yùn)算符優(yōu)先級(jí)比*高,func先跟[]結(jié)合)。跳出這個(gè)括號(hào),看右邊,又遇到圓括號(hào),說明func數(shù)組的元素是函數(shù)類型的指針,它指向的函數(shù)具有int*類型的形參,返回值類型為int。


    用途七:typedef 和存儲(chǔ)類關(guān)鍵字(storage class specifier)?

    這種說法是不是有點(diǎn)令人驚訝,typedef 就像 auto,extern,mutable,static,和 register 一樣,是一個(gè)存儲(chǔ)類關(guān)鍵字。這并不是說 typedef 會(huì)真正影響對(duì)象的存儲(chǔ)特性;它只是說在語句構(gòu)成上,typedef 聲明看起來象 static,extern 等類型的變量聲明。下面將帶到第二個(gè)陷阱:?

    [cpp]?view plaincopy print?
  • typedef?register?int?FAST_COUNTER;?//?錯(cuò)誤??
  •   編譯通不過。問題出在你不能在聲明中有多個(gè)存儲(chǔ)類關(guān)鍵字。因?yàn)榉?hào) typedef 已經(jīng)占據(jù)了存儲(chǔ)類關(guān)鍵字的位置,在 typedef 聲明中不能用 register(或任何其它存儲(chǔ)類關(guān)鍵字)。

    與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

    總結(jié)

    以上是生活随笔為你收集整理的C语言再学习 -- 关键字typedef的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。