文章目錄
- 一、預定義符號
- 二、#define定義常量
- 三、#define定義宏
- 四、宏更函數的對比
- 五、#和##
- 1、#運算符
- 2、##運算符
一、預定義符號
C語言設置了一些預定義符號,可以直接使用,在預處理期間進行處理的。
__FILE__//進行編譯的源文件
__LINE__//文件當前的行號
__DATE__//文件被編譯的日期
__TIME__//文件被編譯的時間
__STDC__//如果編譯器遵循ANSI C,其值為1,否則未定義
測試結果:
二、#define定義常量
#define 用來定義常量時的定義的寫法:
#define MAX 100
邏輯規則是幫后面代碼中出現MAX直接替換成100,這個操作步驟是在預處理階段完成的,一般在用#define定義常量時的名稱用大寫書寫。
使用場景:
三、#define定義宏
#define用來定義宏時使用方法跟函數差不多,但邏輯是替換,在替換時要將變量都用括號括起來,以免發生操作符的優先級問題造成不是我們期望的結果。
使用方式:
#define MAX(x,y) ((x) > (y) ? (x) : (y))
這是寫了一個完成判斷兩數直接較大值的宏,注意宏名稱后面括號要緊貼宏。
使用用例:
通過上面兩個案例可以發現宏在傳參時沒有限制類型,如果函數了話,函數的返回類型是固定的,宏的運行速度更快。
四、宏更函數的對比
宏的優勢:
- 1.在完成代碼量小的計算時,宏的工作時間要比函數小。
- 2.更重要的是函數的參數必須聲明特定的類型。而宏可以適用于各種類型可以用>來比較的類型。宏的類型無關的。
宏的劣勢:
- 每次使?宏的時候,?份宏定義的代碼將插到程序中。除?宏?較短,否則可能?幅度增加程序的?度。
- 宏是沒法調試的。
- 宏由于類型?關,也就不夠嚴謹。
- 宏可能會帶來運算符優先級的問題,導致程容易出現錯。
宏和函數的對比表:
屬性 | #define定義的宏 | 函數 |
---|---|---|
代碼長度 | 每次使用時,宏都會被插入到程序中。除了非常小的宏之外,程序的長度會大幅度增長 | 函數代碼只出現在一個地方;每次使用時,都調用那個地方的同一份代碼 |
執行速度 | 更快 | 存在函數的調用和返回的額外開銷,速度慢一些 |
操作符優先級 | 宏參數的求值是在所有周圍表達式的上下文環境里,除非加上括號,否則鄰近操作符的優先級可能會產生不可預料的后果,所以建議宏在書寫的時候多些括號。 | 函數參數只在函數調用的時候求結果值傳遞給函數。表達式的求值可預測。 |
有副作用的參數 | 參數可能被替換到宏體中的多個位置,如果宏的參數被多次計算,帶有副作用的參數求值可能會產生不可預料的結果。 | 函數參數只在傳參的時候求值易控制。 |
參數類型 | 宏的參數與類型無關,只要對參數的操作是合法的,它就可以使用于任何參數類型。 | 函數的參數是與類型有關的,如不同,就需要不同的函數,任務是不同的。 |
調試 | 宏是不方便調試的 | 函數是可以逐語句調試的 |
遞歸 | 宏是不能遞歸的 | 宏是不能遞歸的 |
五、#和##
1、#運算符
#運算符將宏的?個參數轉換為字符串字?量。它僅允許出現在帶參數的宏的替換列表中。
#運算符所執?的操作可以理解為”字符串化“。
使用例子:
2、##運算符
##可以把位于它兩邊的符號合成?個符號,它允許宏定義從分離的?本?段創建標識符。為記號粘合
這樣的連接必須產??個合法的標識符。否則其結果就是未定義的。這?我們想想,寫?個函數求2個數的較?值的時候,不同的數據類型就得寫不同的函數。
使用例子: