C巨集定義的特殊關鍵字

2022-06-13 10:12:09 字數 3556 閱讀 7618

在分析一些c原始碼時,經常會遇到各種巨集定義操作,本文即總結一下c語言巨集定義中常見的預定義巨集、除錯巨集;巨集的條件編譯用法及特殊的巨集關鍵字用法。

#line

#error

# 用法

## 用法

#pragma 用法

#undef 限定巨集的作用域

一般來講巨集的作用域從 #define 開始直到檔案末尾,但如果需要限定巨集的作用域就可以用 #undef 來限定巨集的作用域,就是該巨集只能作用與 #define … #undef 區間內

常見預定義巨集

預定義巨集也稱為編譯器內建巨集,這些巨集並沒有定義在哪個標頭檔案中,而是編譯器在預處理時會自動處理這些預定義巨集,這裡介紹幾個常用的預定義巨集,其中__func__、__file__、__line__三個巨集在除錯時經常用到,來定位bug,為了方便可以自己定義乙個debug巨集: #define debug printf("%s %s %d\n", __file__,func, __line__);

void

test_1()

執行測試結果:

巨集的條件編譯

所謂條件編譯,也就是在預編譯時,預編譯器可以通過 「條件編譯」 幫你保留某些**、以及幫你去掉某些**,第二階段編譯時就只編譯保留的**,條件編譯可以包含任意內容,可以是 #include 標頭檔案、整個函式、或者函式內部的**塊、變數定義、或是整個檔案的內容(一般標頭檔案中比較多)。條件編譯在linux驅動**以及一些跨平台軟體**中非常常用,針對不同的硬體環境選擇性編譯不同的**塊來提高**的相容性。下面列出常見的條件編譯用法的例子:

#ifdef 和 #ifndef

#ifdef 如果定義了該巨集,就編譯對應的 #endif 之間的**塊;#ifndef 如果沒有定義該巨集,就編譯對應的 #endif 之間的**塊

#define a

#define c

void

test_2()

執行測試**:

e:\c_demo>chong.exe

this is a.

this is b.

#if 用法
void

test_3()

如果 #if 表示式為真,預編譯保留中間**,為假時,則不保留中間**

執行該**如下:

e:\c_demo>chong.exe

預編譯這行**

#if 常常會和 defined、#elif、#else 搭配使用

#define a

#define b

void

test_4()

執行測試**如下:

e:\c_demo>chong.exe

如果 a 和 b 都定義

void

test_5()

執行測試**結果如下:

e:\c_demo>chong.exe

如果以上兩個都不滿足,保留這段**

#line

可以根據自己的需求,修改__line__和__file__的值,也就是修改行號和檔名,並且修改的值永久生效。如下測試**:

void

test_6()

執行以上測試**結果:

e:\c_demo>chong.exe

修改檔名和行號之前:e:\c_demo\chong.c: 65

修改檔名和行號之後:test.c: 100

#error

在linux驅動移植中,往往會修改原始碼中的巨集定義比較多,因為條件編譯需要這些巨集來開啟和關閉,所以在預編譯階段如果就能準確的提示缺少某個巨集的話,可以幫助我們快速排查巨集的錯誤。

void

test_7()

當 pi 沒有定義時,編譯器編譯以上**會列印報錯,提示該巨集沒有定義:

executing task: d:\mingw-w64\mingw64\bin\gcc.exe -g e:\c_demo\chong.c -o chong.exe <

e:\c_demo\chong.c: in function 『test_6』:

e:\c_demo\chong.c:66:2: error: #error pi not defined!

#error pi not defined!

^~~~~

the terminal process terminated with exit code: 1

# 用法

將 # 傳入的引數變成字串,如下**

#define s1(s) #s

#define s2(s) #s" friend"

#define s3(s) "hello "#s

void

test_8()

執行以上**,輸出三個 「hello friend」,通過預編譯後檢視**也能夠看出,該巨集會將引數轉換成字串

## 用法

將兩個識別符號連線在一起,合成乙個識別符號。還是一樣舉個例子說明

#define merge(a, b) a##b

#define print1 printf("print one\n");

#define print2 printf("print two\n");

void

test_9()

#undef merge

執行以上**結果如下:

e:\c_demo>chong.exe

print one

print two

#pragma 用法
*表示僅c++支援,其它的c/c++都支援

alloc_text | comment | init_seg* | optimize | auto_inline | component

inline_depth | pack | bss_seg | data_seg | inline_recursion | pointers_to_members*

check_stack | function | intrinsic | setlocale | code_seg | hdrstop

message | vtordisp* | const_seg | include_alias | once | warning

關於一些常用的巨集定義操作就先記錄到此了,對於 #pragma 巨集的使用,之後有接觸更多用法再作更新…

C語言之關鍵字 巨集定義 條件編譯

區域性變數 特點 注意 區域性變數沒有固定的初始化值,開發中千萬不能使用未初始化的區域性變數 儲存位置 區域性變數儲存在棧中,當作用域結束系統會自動釋放棧中的的區域性變數。特點 如果存在和全域性變數同名的區域性變數,那麼區域性變數會覆蓋全域性變數 注意 全域性變數如果沒有進行初始化,系統缺省會將全域...

C語言中巨集定義 define和關鍵字typedef

define巨集定義是字元替換,typedef是定義型別。define int int是將程式中字元為int的字元全部替換為int,在編譯預處理是進行簡單的字元替換,不做正確性檢查,不管含義是否正確,都進行替換。typedef int int是將int定義為int型的字元型別,是採取像定義變數的方法...

c學習筆記 3關鍵字 巨集與函式定義

好久之前的了,學習c語言的筆記。依舊是老套路,從基礎的變數型別,到函式定義一步步學起 include include 函式定義 與關鍵字 define用於巨集定義 程式中不能更改數值 define mynaem 1234 define age 10 資料型別就不仔細說了 1 資料型別關鍵字 12個 ...