C語言的#define用法


C語言的#define用法

1. 簡單的宏定義

#define MAXSIZE 1000
// 有點像簡單的文本替換

2. define的函數定義

// 同樣類似簡單文本替換
#define Add(a,b) a+b
// 要注意可能會出現運算優先級的問題,比如
c*Add(a,b)*d;
// 本意是c*(a+b)*d,但是計算機可能理解為:c*a+b*d

3. 宏的單行定義和多行定義

宏定義中允許包含兩行以上命令的情形,此時必須在最右邊加上\且該行\不能再有任何字符,連注釋部分都不能有,下面的每行最后的一定要是\,\后面加一個空格都會報錯,更不能跟注釋。

#define max(a,b) \
(((a)>(b))?(a):(b))\

4. 條件編譯

在大規模的開發過程中,特別是跨平台和系統的軟件里,define最重要的功能是條件編譯。

#ifdef WINDOWS
...
#endif
#ifdef LINUX
...
#endif

5. 取消定義宏

//定義宏
#define [MacroName] [MacroValue]
//取消定義
#undef [MacroName]

6. 重復包含(定義)

由於頭文件包含可以嵌套,那么C文件就有可能包含多次同一個頭文件,就可能出現重復定義的問題的。通過條件編譯開關來避免重復包含(重復定義)

#ifndef __headerfileXXX__
#define __headerfileXXX__

//頭文件內容

#endif

7. 重新定義類型

重新定義一些類型,防止由於各種平台和編譯器的不同,而產生的類型字節數差異,方便移植。

補充:關於unsiged char和char

首先在內存中,char與unsigned char沒有什么不同,都是一個字節,唯一的區別是,char的最高位為符號位,因此char能表示-128~127,unsigned char沒有符號位,因此能表示0~255,這個好理解,8個bit,最多256種情況,因此無論如何都能表示256個數字。

在實際使用過程種有什么區別呢?主要是符號位,但是在普通的賦值,讀寫文件和網絡字節流都沒什么區別,反正就是一個字節,不管最高位是什么,最終的讀取結果都一樣,只是你怎么理解最高位而已,在屏幕上面的顯示可能不一樣。

二者的最大區別是:但是我們卻發現在表示byte時,都用unsigned char,這是為什么呢?首先我們通常意義上理解,byte沒有什么符號位之說,更重要的是如果將byte的值賦給int,long等數據類型時,系統會做一些額外的工作。如果是char,那么系統認為最高位是符號位,而int可能是16或者32位,那么會對最高位進行擴展(注意,賦給unsigned int也會擴展)而如果是unsigned char,那么不會擴展。最高位若為0時,二者沒有區別,若為1時,則有區別了。同理可以推導到其它的類型,比如short, unsigned short,等等。

typedef unsigned char boolean;     /* Boolean value type. */

8. 一些常用用法

1. 得到一個field在結構體中的偏移量

#define OFFSETOF(type, field)  ((size_t)&(((type *)0)->field))

(type*)0表示把0地址當成type類型的指針 ((type *)0)->field表示對於

域的變量。前面加上&表示取得地址(也就是相對於0的偏移量),然后將該偏移量轉換為size_t類型的數據

2. 得到一個結構體中field所占用的字節數

#define FPOS( type, field ) ( (dword) &(( type *) 0)-> field ) 

3. 按照LSB格式把兩個字節轉化為一個Word

#define  FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )

4. 得到一個變量的地址(word寬度)

#define  B_PTR(var) ((byte*)(void *) &(var))

#define  W_PTR( var )  ((word *)(void *) &(var))

5. 得到一個字的高位和低位字節

#define  WORD_LO(xxx)  ((byte) ((word)(xxx) & 255))

#define  WORD_HI(xxx)  ((byte) ((word)(xxx) >> 8))

9. 使用一些宏跟蹤調試

五個預定義的宏名:

__LINE__ 及 __FILE__ //宏指示,#line指令可以改變它的值,簡單的講,編譯時,它們包含程序的當前行數和文件名。

__DATE__ 宏指令含有形式為月/日/年的串,表示源文件被翻譯到代碼時的日期。

__TIME__ 宏指令包含程序編譯的時間。時間用字符串表示,其形式為:分:秒

__STDC__ 宏指令的意義是編譯時定義的。一般來講,如果__STDC__已經定義,編譯器將僅接受不包含任何非標准擴展的標准C/C++代碼。如果實現是標准的,則宏__STDC__含有十進制常量1。如果它含有任何其它數,則實現是非標准的。;

// 定義_DEBUG
#ifdef _DEBUG

#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)

#else

#define DEBUGMSG(msg,date)

#endif

10. 一些特殊的標識符

## 是簡單的連接符,#@用來給參數加單引號,#用來給參數加雙引號即轉成字符串。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM