C語言深度解剖 預處理

2021-09-27 08:57:35 字數 4260 閱讀 3356

1、line 表示正在編譯的檔案的行號,

2、file 表示正在編譯的檔案的名字,

3、date 表示編譯時刻的日期字串,

4、time 表示編譯時刻的時間字串,

5、stdc 判斷該檔案是不是定義成標準c程式。

一、巨集定義

1、數值巨集常量

#define pi 3.141592654

#define error_poweroff -1

2、字串巨集常量

#define eng_path_1  e:\english\listen_to_this\listen_to_this_3
3、用define 巨集定義注釋符號「 ? 」

#define bsc //

#define bmc /*

#define emc */

(d) bsc my single-line comment

(e) bmc my multi-line comment emc

(d) 和 (e) 都是錯誤的 ,原因:注釋先於預處理指令被處理,當這兩行被展開成「 // … 」 或 「/ * … * /」 時,注釋已經處理完畢,此時再出現「 // … 」 或 「/ * … * /」自然錯誤。因此,試圖用巨集開始或結束一段注釋是不行的

4、用define 巨集定義表示式

(1)使用巨集定義表示式時,不要吝嗇括號。

(2)巨集函式被呼叫時,是以實參代換形參,而不是 「 值傳送 」

5、巨集定義中的空格

#define sum (x) (x) + (x)

定義了乙個巨集:sum 其代表的是(x) (x) + (x)

空格僅在定義的時候有效,在使用這個巨集函式的時候 ,空格會被編譯器忽略。

6、#undef

(1)作用:用來撤銷巨集定義

(2)巨集的生命週期從#define開始到 #undef 結束

二、條件編譯

1、條件編譯的功能:使得我們可以按不同的條件去編譯不同的程式部分,因而產生不同的目標**檔案。

2、條件編譯的三種形式:

①   #ifdef 識別符號

程式段1

#else

程式段2

#endif

② #ifndef 識別符號

程式段1

#else

程式段2

#endif

③ #if 常量表示式

程式段1

#else

程式段2

#endif

三、檔案包含
格式一:

#include 亦稱標頭檔案

表示預處理要到系統規定的路徑中去獲得這個檔案(即c編譯系統提供的

並存放在指定子目錄下的標頭檔案),找到檔案後,用檔案內容替換該語句。

格式二:

#include "filename"

表示預處理應在當前目錄中查詢檔案名為filename的檔案;若沒有找到,

則按系統指定的路徑資訊搜素其他目錄。找到檔案後,用檔案內容替換該語句

注意:#include 是將已存在檔案的內容,嵌入到當前的檔案中。

#include 支援相對路徑,. 代表當前目錄 , ..代表上層目錄

四、#error預處理

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

#error error_message
五、#line預處理

1、作用:改變當前行數和檔名稱,它們是在編譯程式中預先定義的識別符號。

#line number[ "filename" ]		[ ]內的檔名可省略

eg:#line 30 a.h 改變當前的行號為30,檔名為 a.h

2、我們知道編譯器對c原始碼編譯的過程中會產生一些中間檔案,通過這條指令,可以保證檔名是固定的,不會被這些中間檔案代替,有利於分析。

六、#pragma預處理

1、作用:設定編譯器的狀態或者是指示編譯器完成一些特定的動作。

2、格式:

#pragma  para 

para 為引數

3、#pragma message

#pragma message("訊息文字")   當編譯器遇到這條指令,就會在

編譯 視窗中將訊息文字列印出來

#ifdef_x86

#pragma message("_x86 macro activated!")

#endif

檢查自己是否定義了 _x86 這個巨集,如果定義了,編譯視窗就會輸出

_x86 macro activated!

4、#pragma code_seg

#pragma code_seg(["section - name"[,  "section - class"]])

他能夠設定程式中函式**存放的**段,當我們開發程式驅動時就會使用到他。

5、#pragma once

只要在標頭檔案的最開始加入這條指令 就能夠保證標頭檔案被編譯一次。

6、#pragma hdrstop

表示 預編譯標頭檔案到此為止,後面的標頭檔案不進行預編譯。

可以用 #pragma startup指定編譯優先順序,如果使用了 #pragma package(smart_init) ,bcb 就會根據優先順序的大小先後編譯。

7、#pragma resource

#pragma resource " *.dfm "		表示把 *.dfm 檔案中的資源加入工程。

*.dfm 中包括窗體外觀的定義

8、#pragma warning

#pragma warning(disable: 4507 34; once: 4385; error: 164)

含義:不顯示 4507 和34 號警告資訊

4385號警告資訊僅報告一次

把164號警告資訊作為乙個錯誤

9、#pragma comment

#pragma comment( ... )

該指令將乙個注釋記錄放入乙個物件檔案或可執行檔案中

10、#pragma pack

(1) 記憶體對齊

struct teststruct1

;sizeof(teststruct1) = 12

(2)如何避免記憶體對齊的影響

struct teststruct2

;sizeof(teststruct2) = 8

#pragma  pack(n)	//編譯器將按照n位元組對齊

#pragma pack() //編譯器將取消自定義位元組對齊方式

(3)對齊的規則:每個成員按其型別的對齊引數(通常是這個型別的大小)和指定對齊引數(這裡是n位元組)中較小的乙個對齊,即min(n, sizeof(item)),並且結構的長度必須為所用過的所有對齊引數的整數倍,不夠就補空位元組。

注意:

①:每個成員分別按照自己的方式對齊,並能最小化長度

②:複雜型別(如結構)的預設對齊方式是它最長的成員的對齊方式,這樣在

成員是複雜型別時,可以最小化長度

③:對齊後的長度必須是成員中最大的對齊引數的整數倍。這樣在處理陣列時

可以保證每一項都邊界對齊。

char a[3] 對齊方式:按1位元組對齊

七、「#」運算子

1、字串中包含巨集引數,可以使用「#」,可以把語言符號轉化為字串。

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

sqr(8)

輸出:the square of 8 is 64.

八、「##」運算子

1、也可以用於巨集函式的替換部分,這個運算子把兩個語言符號組合成單個語言符號

#define xname(n)  x ## n

xname(8)

被展開為:x8

「 ## 」 就是個粘合劑,將前後兩部分粘合起來。

c深度解剖 編譯預處理

可以出現在 任何地方 從本行開始之後的 都可以使用該巨集常量 巨集表示式 define min a,b a避免巨集表示式 現 define dim array sizeof array sizeof array int dim int array 因為傳進來的被看成了乙個指標導致始終為1 int m...

C語言深度解剖

1.關鍵字 是編譯器能認識的特殊字串符號。c語言共有32個關鍵字,含sizeof,計算物件所佔記憶體空間的大小。2.定義 建立乙個物件並分配一塊記憶體。3.宣告 告訴編譯器,名字已經匹配到了一塊空間,別的地方不能用它來作為變數名或物件名。宣告沒有分配記憶體,可以出現多次宣告。4.區域性變數 也叫自動...

C語言深度解剖

c語言深度解剖 本書目錄結構如下 第一章 關鍵字 1.1 最寬恒大量的關鍵字auto 1.2 最快的關鍵字register 1.3 最不實名的關鍵字static 1.4 基本資料型別 1.5 最冤枉的關鍵字sizeof 1.6 if else組合 1.7 switch case組合 1.8 do w...