c預處理器和c庫

2021-06-21 14:22:10 字數 2907 閱讀 8621

1.翻譯程式第一步

在預處理之前,編譯器要進行幾部翻譯處理,主要完成以下三方面工作:

第一:把源**中出現的字元對映到源字符集,處理多位元組字元和是c外觀更加國際化的三元字元擴充套件。

第二:查詢反斜線後緊跟換行符的例項並刪除這些例項,即將類似下面的兩個物理行轉行成

printf(「 it is a beatu\

ful girl");

轉換成乙個邏輯行:

printf("it is a beatuful girl");
以為預處理表示式的長度是乙個邏輯行。

第三:將文字劃分成預處理的語言符號串行和空白字元及注釋序列。並用乙個空格代替注釋。

2.#define

指令可以出現在檔案的任何部分,其作用域從定義出現的位置到檔案的結尾。

#define two 2

#define ow "oscar wilde"

#define four two*two

#define px printf("x is %d.\n",x)

每個#define行由三部分組成。第一部分指令#define本身。第二部分縮略語,即我們稱為的巨集(本例中的稱為類物件巨集)。巨集的名字中不允許有空格,而且遵循c變數的命名規則。第三部分稱為替換列表。

從巨集變為最終的替換文字的過程稱為巨集展開。

大多數的數字常量應該使用符號常量。這樣會使程式更加的清楚,可移植。

3.語言符號

從技術角度看,系統把巨集的主體當做語言符號(token)型別字串,而不是字元型字串。c預處理器中語言符號是巨集定義主體中的單獨的「詞」。用空白字元把這些詞分開

#define four 2*2

#define six 2 * 3

第乙個定義中有乙個語言符號2*2,而第二個定義中有三個語言符號2、*、3。。在處理主體中的多個空格時,字元型字串和語言型字串採用不同的方法。字元型字串把空格也當做主體的一部分,而語言型字串只把空格當做分隔語言符號的符號

4.類函式巨集

通過使用引數可以建立和函式外形和作用類似的類函式巨集。其引數也用圓括號括起來。

#define square(x) x*x
在程式中可以這樣使用

z = square(2)
由於預處理器不進行計算,而只進行文字替換,如果使用不當會產生許多意想不到錯誤。

z = square(x+2)

z = 100/square(2)

第乙個展開後變為z = x + 2 * x + 2;第二個展開後變為z = 100 / 2 * 2;

所以在定義類函式巨集事要用圓括號括住每個引數,並括注巨集的整體定義。比如:

#define max (x, y) ((x) > (y) ? (x) : (y))
利用巨集引數建立字串: #運算子

如果想在字串中包含巨集引數。在類函式巨集的替換部分中,#符號用作乙個預處理運算子,它就可以吧語言符號轉化為字串。x是乙個巨集參量,#x就可以把引數轉換為相應的字串。

預處理器的粘合劑:##運算子

#define xname(n) x ## n
這樣呼叫 xname(4),展開後:x4。進行語言符號的粘合操作。

5.#include 標頭檔案

標頭檔案中最常見的內容:

明顯常量 :stdio.h中的eof、null和bufsize等

巨集函式     :getchar()

函式宣告:

型別定義:

另外,將多個源檔案共享的外部變數放到標頭檔案中。

包含標頭檔案的另一種情況:使用具有檔案作用域、內部鏈結和const限定詞的變數和陣列。使用const可以避免值被意外的修改。使用static後,每個包含該標頭檔案的檔案都獲得乙份該常量的副本。因此不需要在乙個檔案中進行定義宣告,在另乙個檔案中進行引用宣告。

6.條件編譯

使用這些指令告訴編譯器:根據編譯時的條件節後或忽略資訊塊。

(1)#ifdef、#else和#endif

#ifdef vis

#include 「horse.h」

#define ata 5

#else

#include 「cow.h」

#define btb 5

#endif

(2)#ifndef指令

#ifndef可以和#else、#endif一起使用。#ifndef判斷後面的識別符號是否未定義。#ifndef通常用來定義此前未定義的常量。

#ifndef size

#define size 100

#endif

該指令通常還用來防止多次包含同一檔案。

/*things.h*/

#ifndef things_h_

#define things_h_

/*標頭檔案的其餘部分*/

#endif

(3)#if和#elif指令

#if指令更像c中的if;#if常跟常量表示式。如果表示式為非零值,則表示式為真。

#if sys == 1

#include "i.h"

#elif

#include "j.h"

#elif

#include "g.h"

#endif

(4)#line 和#error

#line指令用於重置__line__和__file__巨集報告的行號和檔名。

(5)#pragm將編譯器指令置於源**中。

C預處理器和C庫

編譯程式之前,先由預處理器檢查程式。根據程式中使用的預處理器指令,預處理器用符號縮略語所代表的內容替換程式中的縮略語。1.編譯器的處理步驟 2 編譯器查詢反斜線後面緊跟換行符的例項並刪除這些例項。將多個物理行替換為乙個邏輯行。3 編譯器將文字劃分為預處理的語言符號 token 序列和空白字元及注釋序...

C 標準庫 預處理器

1.預處理器 1.1 使用 代表返回乙個帶引號的字串,如 define to string s s to string hello 可以表示成 hello 1.2 使用 代表連線前後的內容,如 define concatenate x,y x y concatenate 5,2 可以表示成52 1....

C 預處理器

偶爾翻c 的教材,看到了一些以前自己不太關注的角落。參考教材 c 大學教程 harvey m.deitel 和paul james deitel著。預處理發生在編譯之前,包括把其他檔案包含到要編譯的檔案中 定義符號常量和巨集 程式 的條件編譯以及預處理指令的條件執行。對應的,預處理指令有 檔案包含命...