關於預處理

2021-09-30 12:19:04 字數 3295 閱讀 1775

1. 能用巨集定義開始或者結束一段注釋嗎?

例如:#define bsc //

#define bmc /*

#define emc */

那麼:bsd my single-line comment

bmc my single-line comment emc

正確嗎?

答案是不正確的,這是因為

注釋先於預處理指令被處理

,當這兩行被展開成//...或者/**/時,注釋已被處理完畢,此時再出現替換而成的//或者自然會發生錯誤。

2. 請看下面這樣一組巨集定義,z的值最後是多少?

#define x 3

#define y x*2

#undef x

#define x 2

int z = y;

答案:4;

當**在編譯的時候,進行替換,而#undef是解除x的定義,也就是上面的3;再解除之後,重新定義了x為2,這個時候y = 2*2 = 4.

3. 條件編譯的幾種形式;

a.如果標示符已被#define命令定義過,則對程式段1進行編譯;否則對程式段2進行編譯,格式如下:

#ifdef 標示符

程式段1

#else

程式段2

#endif

其中,如果程式段2為空,#else也可以沒有。

b. 如果標示符未被#define命令定義過,則對程式段1進行編譯,與第一種形式功能相反,格式如下: 

#ifndef 標示符

程式段1

#else

程式段2

#endif

c. 如果常量表示式的值為真(非0),則對程式段1進行編譯,否則對程式段2進行編譯,因此可以使程式在不同

條件下,完成不同的功能,格式如下:

#if 常量表示式

程式段1

#else

程式段2

#endif

d. #ifndef和#define

#ifndef x//先測試x是否被巨集定義過

#define x

程式段1 //如果x沒有被巨集定義過,定義x,並編譯程式段1

#endif

程式段2 //如果x已經定義過了則編譯程式段2的語句,「忽視」程式段1。

條件指示符#ifndef 的最主要目的是防止標頭檔案的重複包含和編譯。了解:條件編譯當然也可以用條件語句來實現。 但是用條件語句將會對整個源程式進行編譯,生成的目標**程式很長,而採用條件編譯,則根據條件只編譯其中的程式段1或程式段2,生成的目標程式較短。如果條件選擇的程式段很長,採用條件編譯的方法是十分必要的。

《標識》在理論上來說可以是自由命名的,但每個標頭檔案的這個「標識」都應該是唯一的。標識的命名規則一般是頭檔名全大寫,前後加下劃線,並把檔名中的「.」也變成下劃線,如:stdio.h

#ifndef _stdio_h_

#define _stdio_h_

......

#endif

4. 關於#error預處理

作用:編譯程式時,只要遇到#error就會生成乙個編譯錯誤提示訊息,並停止編譯。

語法格式:#error error-message

注意:巨集串error-message不用雙引號包圍。

這個命令一般是放在異常處理**段中,如果出現編譯錯誤,可以輸出資訊幫助你確定出現錯誤的地方。

5. 關於#line 預處理

作用:改變當前行數和檔名稱

形式:#line number["filename"]

注意:內的檔名可以省略。

例如:#line 30 "a.h"或者#line 30

改變當前行號為30,當前檔名為a.h;這樣做有什麼意義?

平時我們基本上用不上,有些時候還是有一點點作用的,那就是在編譯器的編寫中,我們知道編譯器對c原始碼編譯過程中會產生一些中間檔案,通過這條命令,可以保證檔名是固定的,不會被中間檔案代替,有利於進行分析。

6. 關於#pragma預處理

作用:設定編譯器的狀態或者指示編譯器完成一些特定的動作;#pragma指令對每個編譯器給出了乙個方法,在保持c和c++語言完全相容的情況下,給主機或者os專有的特徵,因為每個編譯器上的編譯指示都不同。

格式:#pragma para

說明:para為引數,引數有很多種,例如:

a. #pragma message

eg:#ifdef _x86

#pragma message("_x86 macro activated!")

#endif

說明:當我們定義了_x86這個巨集之後,應用程式在編譯時就會在編譯輸出視窗顯示

"_x86 macro activated!",這樣我們就不會因為忘記自己定義的一些特定的巨集而苦思冥想了。

b. #pragma once

作用:保證標頭檔案被編譯一次。

c. #pragma comment(...)

作用:將乙個注釋記錄放入乙個物件檔案或者可執行檔案中,常用lib關鍵字,可以幫我們連入乙個庫檔案,例如:

#pragma comment(lib,"user32.lib")

該指令用來將user32.lib庫檔案加入到本工程中,有時候目錄分層要用到.和..,其中.代表當前目錄,..代表上一級目錄。

d. #pragma code_seg

作用:設定程式中函式**存放的**段,經常用在驅動開發中。

...還有很多,so much...

如果想知道每種引數代表什麼作用,可以查閱相關資料,或者用到的時候可以查閱相關知識。

7. #運演算法

#也可以當預處理用?答案是yes.

eg:#define sqr(x) printf("the square of x is %d.\n",((x)*(x)));

如果這樣使用巨集:

sqr(8);

則輸出為:

the square of x is 64.

這裡的x是被當做普通文本來處理。

假如你確定希望在字串中包含巨集引數,那我們就可以使用"#",它可以把語言符號轉化為字串

eg:#define sqr(x) printf("the square of "#x" is %d.\n",((x)*(x)));

如果使用sqr(8);

則輸出的是:

the square of 8 is 64.

8. ##預算符

作用:用作巨集函式的替換部分,把兩個語言符號組合成單個語言符號。

eg:#define xname(n) x##n

如果使用xname(8)

則展開後為:

x8##就相當於乙個粘合劑,將前後兩部分粘合起來。

(the end)

c 預處理和預處理命令

預處理發生在編譯之前,預處理輸出的是乙個單一的檔案,這個檔案被送到編譯器,進行編譯。每條預處理命令都控制預處理器的行為。每條預處理命令佔據一行,有以下的格式 character 預處理命令 one of define,undef,include,if,ifdef,ifndef,else,elif,e...

mysql 預處理語句 in MySQL預處理語句

預製語句的sql語法基於三個sql語句 prepare stmt name from preparable stmt execute stmt name using var name var name prepare stmt name prepare語句用於預備乙個語句,並賦予它名稱stmt na...

mysql 預處理 PHP MySQL 預處理語句

php mysql 預處理語句 預處理語句對於防止 mysql 注入是非常有用的。預處理語句及繫結引數 預處理語句用於執行多個相同的 sql 語句,並且執行效率更高。預處理語句的工作原理如下 預處理 建立 sql 語句模板併發送到資料庫。預留的值使用引數 標記 例如 insert into mygu...