您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“C語言宏的定義與使用方法是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“C語言宏的定義與使用方法是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
#define是預處理器處理的單元實體之一
#define 定義的宏可以出現在程序的任意位置
#define 定義之后的代碼都可以使用這個宏
#define 定義的宏常量可以直接使用
#define 定義的宏常量本質為字面量
下面的宏常量定義正確嗎?
編寫代碼來測試:
#define ERROR -1 #define PATH1 "D:\test\test.c" #define PATH2 D:\test\test.c #define PATH3 D:\test\ test.c int main() { int err = ERROR; char* p1 = PATH1; char* p2 = PATH2; char* p3 = PATH3; }
先使用gcc -E Test.c -o Test.i 進行預編譯,預編譯沒有報錯,結果如下:
# 1 "Test.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "Test.c" int main() { int err = -1; char* p1 = "D:\test\test.c"; char* p2 = D:\test\test.c; char* p3 = D:\testtest.c; }
直接進行編譯,發現 char* p2 = PATH2; char* p3 = PATH3; 報錯
這說明宏定義是正確的,但是編譯是過不了的,只是
#define PATH2 D:\test\test.c
#define PATH3 D:\test\
不符合語法規范。
#define 表達式的使用類似函數調用
#define 表達式可以比函數更強大
#define 表達式比函數更容易出錯
強大之處其中之一就是可以求數組的大小,這是不能編寫函數辦到的。
下面看一段宏表達式的代碼:
#include <stdio.h> #define _SUM_(a, b) (a) + (b) #define _MIN_(a, b) ((a) < (b) ? (a) : (b)) #define _DIM_(a) sizeof(a)/sizeof(*a) int main() { int a = 1; int b = 2; int c[4] = {0}; int s1 = _SUM_(a, b); int s2 = _SUM_(a, b) * _SUM_(a, b); int m = _MIN_(a++, b); int d = _DIM_(c); printf("s1 = %d\n", s1); printf("s2 = %d\n", s2); printf("m = %d\n", m); printf("d = %d\n", d); return 0; }
下面為輸出結果,但是 s2 我們預期的結果應該是 9,m 的值我們預期的結果應該是 1,這是怎么回事呢?
下面進行預編譯看看代碼到底是怎么運行的,輸入 gcc -E Test.c -o Test.i
int main() { int a = 1; int b = 2; int c[4] = {0}; int s1 = (a) + (b); int s2 = (a) + (b) * (a) + (b); int m = ((a++) < (b) ? (a++) : (b)); int d = sizeof(c)/sizeof(*c); printf("s1 = %d\n", s1); printf("s2 = %d\n", s2); printf("m = %d\n", m); printf("d = %d\n", d); return 0; }
通過上面宏定義的替換,我們很容易知道為什么結果跟我們想的不一樣。
宏表達式被預處理器處理,編譯器不知道宏表達式的存在
宏表達式用“實參”完全替代形參,不進行任何運算
宏表達式沒有任何的“調用”開銷
宏表達式中不能出現遞歸定義
所以,下面遞歸定義就是錯誤的:
宏定義的常量或表達式是否有作用域限制?(沒有)
下面看一個宏作用域分析的代碼:
#include <stdio.h> void def() { #define PI 3.1415926 #define AREA(r) r * r * PI } double area(double r) { return AREA(r); } int main() { double r = area(5); printf("PI = %f\n", PI); printf("d = 5; a = %f\n", r); return 0; }
下面為輸出結果:
作用域的概念是針對 C 語言中的變量和函數,不針對宏。宏表達式被預處理器處理,編譯器不知道宏表達式的存在。
宏 | 含義 | 示例 |
_FILE_ | 被編譯的文件名 | file1.c |
_LINE_ | 當前行號 | 25 |
_DATE_ | 編譯時的日期 | Jan 31 2021 |
_TIME_ | 編譯時的時間 | 17:01:01 |
_STDC_ | 編譯器是否遵循標準C規范 | 1 |
下面看一個宏使用的綜合示例:
#include <stdio.h> #include <malloc.h> #define MALLOC(type, x) (type*)malloc(sizeof(type)*x) #define FREE(p) (free(p), p=NULL) #define LOG(s) printf("[%s] {%s:%d} %s \n", __DATE__, __FILE__, __LINE__, s) #define FOREACH(i, m) for(i=0; i<m; i++) #define BEGIN { #define END } int main() { int x = 0; int* p = MALLOC(int, 5); LOG("Begin to run main code..."); FOREACH(x, 5) BEGIN p[x] = x; END FOREACH(x, 5) BEGIN printf("%d\n", p[x]); END FREE(p); LOG("End"); return 0; }
下面為輸出結果:
可以看到宏定義是很強大的,可以打印出日期,文件名,行號,不使用宏定義很難實現。
讀到這里,這篇“C語言宏的定義與使用方法是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。