C語言學習筆記 6編譯預處理

2021-07-14 14:45:12 字數 2916 閱讀 6139

*****2023年1月21日10:08:37

*韓–

*概述:

1、檔案包含

2、巨集定義與取消巨集定義

3、條件編譯

4、assert斷言與靜態斷言

預處理命令兩種形式:

# include 《檔名》

# include "檔名"

//檔名可以是包含檔案的路徑名,如:# include //此時兩種形式沒有什麼區別 # include "d:\test\myfile.h"

預處理命令作用:

替換。//檔案包含即用檔案的內容取代預處理命令列

沒有路徑名時兩種形式區別:

# include 《檔名》 //系統到指定的標準目錄

# include "檔名" /*系統首先在當前目錄中尋找被包含檔案,

如果找不到,去指定的標準目錄*/

被包含檔案的字尾名字位置可由自己確定

巨集定義:# define

用乙個識別符號(稱為「巨集」)來代表乙個字串

被定義為「巨集」的識別符號稱為「巨集名」

編譯預處理時「巨集名」被巨集定義中的字串代替,稱為「巨集展開」「巨集代換」

巨集定義分類

1)無參巨集定義

巨集定義中表示式兩邊的括號不能少,使用巨集定義應保證在巨集展開時不發生錯誤

用引號括起來的與巨集名相同的識別符號不做替換;

2)帶參巨集定義

一般形式:

// # define 識別符號(識別符號,識別符號,……,識別符號) 字串//

第乙個識別符號與括號之間沒有空格;字串中每乙個識別符號應有括號;

帶參巨集定義時,形參不分配記憶體單元,不必做型別說明

巨集展開後會使源程式增長,適合比較簡短的表示式

巨集呼叫中允許引數為空,多個引數時,不要省略逗號

==》可變引數巨集定義:

引數可變函式eg:

/*int printf(const char* format,……)*/省略號表示引數可變

可變引數巨集的定義:

/*# define debug(format,……) printf(formats, _va_args_)*/

_va_args_負責把省略號部分傳遞給巨集

用可變引數巨集列印除錯資訊

# include 

# define dubug //除錯完之後把此行刪掉就可以了

# ifdef dubug

# define msg(fmt,……) printf(fmt,_va_args_);

# else

# define msg(fmt,……)

# endif

int main

==》通用型別巨集

eg:# define sin(x) _generic((x),long double:sinl,double:sinf,default:sin)(x)

取消巨集定義

形式:

/* # undef 識別符號 */

這裡的識別符號是指之前由#define定義過的巨集名

終止巨集名的作用域,使之前的巨集定義被取消

大型軟體的程式設計,引入一些別處提供的標頭檔案,為了防止巨集名的衝突,可以用

/*#include#undef size

#define size 100

*/還可以保證所呼叫的是乙個實際函式而不是巨集

/*#undef getchar

int getchar(void)

*/

//defined運算子:defined(識別符號)或defined 識別符號

用來判斷識別符號是否被#define定義了,定義過,值為1,否則為0

//#if、#ifdef、#ifndef

1)類似於 if-else

#if 常量表示式

程式塊#elif 常量表示式

程式塊……

#else

程式塊#endif

2)若#ifdef後的識別符號已經被#define標記過則編譯後面的程式塊

#ifdef 識別符號

程式塊#elif 識別符號

程式塊……

#else

程式塊#endif

3)若#ifndef後的識別符號沒有被#define標記過則編譯後面的程式塊

#ifndef 識別符號

程式塊#elif 識別符號

程式塊……

#else

程式塊#endif

//#ifdef 識別符號 == #if defined(r)

應用: 避免多次包含乙個標頭檔案

封閉不能注釋掉的**

#if 0

……#endif

除錯程式:除錯時只需在檔案首加「#define debug 」,除錯完成刪掉

#ifdef debug

……#endif

1)assert斷言

巨集,被定義在標準標頭檔案「assert.h」,只能在程式執行出錯時產生除錯資訊

形式:assert(condition)

//如果condition值為真,什麼也不發生,如果值為假,輸出錯誤資訊

頻繁的assert呼叫影響程式效能

除錯結束後,在標頭檔案前加#define ndebug可以禁用assert呼叫

2)靜態斷言

在編譯時進行檢查,不會產生額外開銷,形式:

_static_assert (整型常量表示式,"字串(斷言失敗時輸出的提示資訊)");

c語言學習筆記 預處理

編譯的幾個階段 我們平時使用的編譯器,其實準確來講應該叫編譯工具鏈,因為其中包括了不止一種編譯器,他們之間相互銜接,完成將程式轉化為二進位制 的功能 主要分為4個階段,預處理 c 彙編.s 編譯.o 鏈結 axf hex bin 四個過程 常用預處理指令 include if,end,define ...

C語言學習之預處理

編譯乙個c程式需要經過預處理 編譯 彙編和鏈結幾個步驟,預處理是在編譯之前所做的工作,預處理其實就是對原始檔做一些編輯工作,為編譯做好準備。1.條件編譯 if constant expression endif 或者 if constant expression elif constant expr...

c語言學習四 預處理指令

預處理指令 意義用法 include 檔案包含 include define 巨集定義 define pcchar char undef 撤銷定義過的巨集 undef pcchar if else elif endif 條件編譯,true就編譯 關心巨集定義,也關心巨集真假 if elif else...