c預處理器在源**編譯之前對其進行一些文字性質的操作。它的主要任務包括刪除注釋、插入被#include指令包含的檔案的內容、定義和替換由#define指令定義的符號以及確定**的部分內容是否應該根據一些條件編譯指令進行編譯。
1.預定義符號
預處理器定義的符號,它們的值或者是字串常量,或者是十進位制數字常量。__file__和__line__在確認除錯輸出的**方面很有用處,__date__和__time__常常用於在被編譯的程式中加入版本資訊,__stdc用於哪些在ansi和非ansi環境都必須進行編譯的程式中結合條件編譯。
2.#define
1)文字替換的作用,#define name stuff
2)巨集,允許把引數替換到文字中,#define square(x) (x) *(x)
3)#define替換,a)在呼叫巨集時首先對引數進行檢查,看看是否包含了任何由#define定義的符號,若是它們首先被替換;b)替換文字隨後被插入到程式中原本文字的位置,對於巨集,引數名被它們的值所替代;c)最後再次對結果文字進行掃瞄,看是否包含任何由#define定義的符號,若是就重複上述處理過程。
4)巨集與函式,a)**很可能比實際執行小型計算工作**量少;b)巨集定義與傳達型別是無關的,函式則必須制定型別。
5)帶***的巨集引數,當巨集引數在巨集定義**現的次數超過一次時,若這個引數具有***,可能導致不可預料的結果。***就是在表示式求值時出現永久性的效果。例如 x+1無***,x++就具有***。
6)命名約定,巨集和函式的不同涉及**長度、執行速度、操作符優先順序、引數求值和引數型別等方面。
7)#undef,這條預處理指令用於移除乙個巨集定義。
8)命令列定義,許多c編譯器提高一種能力,允許在命令列中定義符號,用於啟動編譯。當根據同一原始檔編譯乙個程式的不同版本時,這個特性是很有用的。
3.條件編譯
使用條件編譯,可以選擇**的一部分是被正常編譯還是完全忽略,用於支援的基本結構是#if指令和與其匹配的#endif指令。
#if constant-expression
statements
#elif constant-expression
other statements
#else
other statements
#endif
1)是否被重定義,測試乙個符號是否被重定義是可能的,在條件編譯中完成這個任務往往更方便,因此程式如果並不需要控制編譯的符號所控制的特性,它就不需要被定義。
#if defined(symbol)
#ifdef symbol
#if !define(symbol)
#ifndef symbol
2)巢狀指令
#if defined(os_unix)
#ifdef option1
uinx_version_of_option1();
#endif
#ifdef option2
uinx_version_of_option2();
#endif
#elif #define(os_msdos)
#ifdef option2
msdos_version_of_option2();
#endif
#endif
4.檔案包含
1)函式庫包含,編譯器支援兩種不同型別的#include檔案包含:函式庫檔案和本地檔案。
2)本地檔案包含,標準編譯器自行決定是否把本地形式的#include和函式庫形式的#include區別對待。
3)巢狀檔案包含,在乙個將被其它檔案包含的檔案中使用#include指令是可能的。巢狀#include檔案的乙個不利之處在於它使得我們很難判斷原始檔之間的真正依賴關係。
5.其它指令
#error指令允許生成錯誤資訊。#progma指令是另一種機制,用於支援因編譯器而異的特性。#line指令允許告訴編譯器下一行輸入的行號,如果它加上可選內容,它還將告訴編譯器輸入原始檔的名字。
6.警告的總結
1)不要在乙個巨集定義末尾加上分號,使其成為一條完整的語句;
2)在巨集定義中使用引數,但忘了在它們周圍加上括號;
3)忘了在整個巨集定義的兩邊加上括號;
7.程式設計提示總結
1)避免用#define指令定義可以用函式實現的很長序列的**。
2)在那些對表示式求值巨集中,每個巨集引數出現的地方都應該加上括號,並且在整個巨集定義的兩邊加上括號;
3)避免使用#define巨集建立一種新語言;
4)採用命名約定,使程式設計師很容易看出某個識別符號是否為#define巨集;
5)只要合適就應該使用檔案包含,不必擔心它的額外開銷;
6)標頭檔案只應該包含一組函式和(或)資料的宣告;
7)把不同集合的宣告分離到不同的標頭檔案中可以改善資訊隱蔽;
8)巢狀的#include檔案使我們很難判斷原始檔之間的依賴關係。
《C和指標》第14章 預處理器
14.2.1 巨集 define包括乙個規定,允許把引數替換到文字中,這種實現通常稱為巨集 macro define square x x x 則程式中的square 5 會被替換成 5 5 警告 例1 a 5 printf d n square a 1 會被替換成5 1 5 1,列印結果是11,不...
C和指標(第14章 預處理器)
程式編寫,編譯第一步就是巨集的宣告,也稱預處理器階段,在編譯之前,有刪除注釋,插入被 include指令包含的檔案的內容 和 define所替換的符號等。14.1 五種預處理符號 file name.c 進行編譯的源檔名 line 25 檔案當前的行號 date jan 14 2019 檔案被編譯的...
C和指標14章 預處理器筆記
1.define define name stuff 當有name出現時,預處理器就會把它替換成stuff 當stuff非常長的時候,可以分成好幾行,除了最後一行外,每行都要加上乙個反斜槓 define debug print printf file s line d x d,y d,z d fil...