日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > > strongerHuang
[導讀]在C語言編程中,typedef 和?#define是最常用語句,可能很多工作過兩三年的工程師都沒有去深究過它們的一些用法和區(qū)別。


素材來源:網(wǎng)絡

編輯整理:strongerHuang


在C語言編程中,typedef 和?#define是最常用語句,可能很多工作過兩三年的工程師都沒有去深究過它們的一些用法和區(qū)別。



一、typedef的用法

在C/C++語言中,typedef常用來定義一個標識符及關鍵字的別名,它是語言編譯過程的一部分,但它并不實際分配內存空間,比如:

typedef int INT;typedef (int*)???pINT;typedef unsigned int uint32_t


typedef可以增強程序的可讀性,以及標識符的靈活性,但它也有“非直觀性”等缺點。


二、#define的用法

#define為一宏定義語句,通常用它來定義常量(包括無參量與帶參量),以及用來實現(xiàn)那些“表面似和善、背后一長串”的宏,它本身并不在編譯過程中進行,而是在這之前(預處理過程)就已經(jīng)完成了,但也因此難以發(fā)現(xiàn)潛在的錯誤及其它代碼維護問題,比如:

#define INT int#define TRUE 1#define Add(a,b) ((a)+(b));#define Loop_10 for (int i=0; i<10; i++)


在Scott Meyer的Effective C++一書的條款1中有關于#define語句弊端的分析,以及好的替代方法,大家可參看。


三、typedef與#define的區(qū)別

從以上的概念便也能基本清楚,typedef只是為了增加可讀性而為標識符另起的新名稱(僅僅只是個別名),而#define原本在C中是為了定義常量。到了C++,const、enum、inline的出現(xiàn)使它也漸漸成為了起別名的工具。


有時很容易搞不清楚 #define 與 typedef 兩者到底該用哪個好,如#define INT int這樣的語句,用typedef一樣可以完成,用哪個好呢?


我主張用typedef,因為在早期的許多C編譯器中這條語句是非法的,只是現(xiàn)今的編譯器又做了擴充。為了盡可能地兼容,一般都遵循#define定義“可讀”的常量以及一些宏語句的任務,而typedef則常用來定義關鍵字、冗長的類型的別名。



宏定義只是簡單的字符串代換(原地擴展),而typedef則不是原地擴展,它的新名字具有一定的封裝性,以致于新命名的標識符具有更易定義變量的功能。


比如代碼:

typedef (int*) pINT;

以及:

#define pINT2 int*;


效果相同?實則不同!實踐中見差別:pINT a,b;的效果同int *a; int *b;表示定義了兩個整型指針變量。而pINT2 a,b;的效果同int *a, b;


表示定義了一個整型指針變量a和整型變量b。


四、typedef的用途

用途一:

定義一種類型的別名,而不只是簡單的宏替換。


可以用作同時聲明指針型的多個對象。比如:

char* pa, pb; //這多數(shù)不符合我們的意圖,它只聲明了一個指向字符變量的指針,和一個字符變量;


以下則可行:

typedef char*??PCHAR;PCHAR??pa,??pb; //同時聲明了兩個指向字符變量的指針


雖然下面(代碼)方式也可行,但相對來說沒有用typedef的形式直觀,尤其在需要大量指針的地方,typedef的方式更省事。

char *pa, *pb;


用途二:

用在舊的C代碼中(具體多舊沒有查),幫助struct。


以前的代碼中,聲明struct新對象時,必須要帶上struct,即形式為:

struct ??結構名? ?對象名,如:

struct tagPOINT1{ int x; int y;}; struct tagPOINT1 p1;


而在C++中,則可以直接寫:結構名? ?對象名,即:

tagPOINT1 p1;


估計某人覺得經(jīng)常多寫一個struct太麻煩了,于是就發(fā)明了:

typedef struct tagPOINT{ int x; int y;}POINT; POINT p1; // 這樣就比原來的方式少寫了一個struct,比較省事,尤其在大量使用的時候


或許,在C++中,typedef的這種用途二不是很大,但是理解了它,對掌握以前的舊代碼還是有幫助的,畢竟我們在項目中有可能會遇到較早些年代遺留下來的代碼。


用途三:

用typedef來定義與平臺無關的類型。


比如定義一個叫 REAL 的浮點類型,在目標平臺一上,讓它表示最高精度的類型為:

typedef long double REAL;


在不支持 long ? double 的平臺二上,改為:

typedef double REAL;


在連 double 都不支持的平臺三上,改為:

typedef float REAL;


也就是說,當跨平臺時,只要改下 typedef 本身就行,不用對其他源碼做任何修改。標準庫就廣泛使用了這個技巧,比如size_t。


另外,因為typedef是定義了一種類型的新別名,不是簡單的字符串替換,所以它比宏來得穩(wěn)健(雖然用宏有時也可以完成以上的用途)。


用途四:

為復雜的聲明定義一個新的簡單的別名。


方法是:在原來的聲明里逐步用別名替換一部分復雜聲明,如此循環(huán),把帶變量名的部分留到最后替換,得到的就是原聲明的最簡化版。舉例如下一些情況。


1.原聲明:

int *(*a[5])(int, char*);


變量名為a,直接用一個新別名pFun替換a就可以了:

typedef int *(*pFun)(int, char*);


原聲明的最簡化版:

pFun a[5];


2.原聲明:

void (*b[10]) (void (*)());


變量名為b,先替換右邊部分括號里的,pFunParam為別名一:

typedef void (*pFunParam)();


再替換左邊的變量b,pFunx為別名二:

typedef void (*pFunx)(pFunParam);


原聲明的最簡化版:

pFunx b[10];


3.原聲明:

doube(*)() (*e)[9];


變量名為e,先替換左邊部分,pFuny為別名一:

typedef double(*pFuny)();


再替換右邊的變量e,pFunParamy為別名二

typedef pFuny (*pFunParamy)[9];


原聲明的最簡化版:

pFunParamy e;


理解復雜聲明可用的“右左法則”:從變量名看起,先往右,再往左,碰到一個圓括號就調轉閱讀的方向;括號內分析完就跳出括號,還是按先右后左的順序,如此循環(huán),直到整個聲明分析完。舉例:

int (*func)(int *p);


首先找到變量名func,外面有一對圓括號,而且左邊是一個*號,這說明func是一個指針;然后跳出這個圓括號,先看右邊,又遇到圓括號,這說明(*func)是一個函數(shù),所以func是一個指向這類函數(shù)的指針,即函數(shù)指針,這類函數(shù)具有int*類型的形參,返回值類型是int。

int (*func[5])(int *);


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


也可以記住2個模式:

type? ?(*)(....)函數(shù)指針

type? ?(*)[]數(shù)組指針


五、typedef的陷阱

陷阱一:

記住,typedef是定義了一種類型的新別名,不同于宏,它不是簡單的字符串替換。比如先定義:

typedef char* PSTR;


然后:

int mystrcmp(const PSTR, const PSTR);


const ? PSTR實際上相當于const ? char*嗎?


不是的,它實際上相當于char*? ?const。


原因在于const給予了整個指針本身以常量性,也就是形成了常量指針char*? ?const。


簡單來說,記住當const和typedef一起出現(xiàn)時,typedef不會是簡單的字符串替換就行。


陷阱二:

typedef在語法上是一個存儲類的關鍵字(如auto、extern、static、register等一樣),雖然它并不真正影響對象的存儲特性,如:

typedef static int INT2; //不可行


編譯將失敗,會提示“指定了一個以上的存儲類”。


推薦閱讀:

FILE、LINE等幾種C標準用法

提高國內訪問 GitHub 速度的幾種方法

百度網(wǎng)盤國際版 Dubox 干凈好用,卻與國內用戶無緣


關注 微信公眾號『strongerHuang』,后臺回復“1024”查看更多內容,回復“加群”按規(guī)則加入技術交流群。


長按前往圖中包含的公眾號關注

免責聲明:本文內容由21ic獲得授權后發(fā)布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除( 郵箱:macysun@21ic.com )。
換一批
延伸閱讀

全球嵌入式技術領域的年度盛會2026嵌入式世界展(Embedded World 2026,簡稱EW26)于3月10日至12日在德國紐倫堡成功舉辦。作為物聯(lián)網(wǎng)和邊緣AI領域的領先企業(yè),Silicon Labs(亦稱“芯科科...

關鍵字: 物聯(lián)網(wǎng) 邊緣AI 嵌入式

3月10日至12日,2026年嵌入式世界展(Embedded World 2026,簡稱EW26)在德國紐倫堡展覽中心成功舉辦。作為領先的邊緣AI與智能音頻等媒體處理技術和芯片解決方案提供商,XMOS以沉浸式演示與技術交...

關鍵字: 邊緣AI 智能音頻 嵌入式

在嵌入式系統(tǒng)開發(fā)中,SoC(System on Chip)的多樣性始終是橫亙在開發(fā)者面前的難題。以某工業(yè)物聯(lián)網(wǎng)網(wǎng)關項目為例,其需同時支持NXP i.MX8M、Rockchip RK3566和Allwinner H616三...

關鍵字: Platform Driver模型 嵌入式

在高性能網(wǎng)絡編程領域,事件驅動模型以其高效的I/O多路復用能力成為主流范式。不同于傳統(tǒng)的多線程/多進程阻塞模型,事件驅動通過單一線程監(jiān)聽多個文件描述符的狀態(tài)變化,以非阻塞方式處理I/O事件,顯著減少了上下文切換開銷和資源...

關鍵字: 事件驅動 C語言

在非易失性存儲器領域,EEPROM(電可擦除可編程只讀存儲器)曾長期占據(jù)主流地位,廣泛應用于各類電子設備的參數(shù)存儲、日志記錄等場景。但隨著工業(yè)控制、汽車電子、醫(yī)療設備等領域對存儲性能提出更高要求,F(xiàn)RAM(鐵電隨機存取存...

關鍵字: 存儲器 可編程 嵌入式

康佳特將aReady.COM擴展至Arm架構模塊,基于恩智浦i.MX 95處理器打造應用就緒的軟硬件構建模塊,集成操作系統(tǒng)、系統(tǒng)整合與IoT連接能力,賦能高價值應用快速落地

關鍵字: 處理器 IoT 嵌入式

3月12日,2026年中國家電及消費電子博覽會(以下簡稱:AWE 2026)在上海盛大開幕。展會現(xiàn)場,場景化、系統(tǒng)化、一體化的家電解決方案成為行業(yè)焦點,消費者對家電的關注也已從基礎的尺寸匹配,延伸至對“空間秩序感”和“視...

關鍵字: 消費電子 蒸烤箱 嵌入式

超高效NPU IP在資源受限設備中推進邊緣AI,因而獲得認可

關鍵字: 人工智能 嵌入式 NPU

上海2026年3月12日 /美通社/ -- 3月12日,2026中國家電及消費電子博覽會(AWE 2026)在上海新國際博覽中心和東方樞紐國際商務合作區(qū)展區(qū)正式啟幕。本屆展會以"AI科技?慧享未來"為...

關鍵字: 西門子 博世 嵌入式 洗碗機
關閉