1
、所有的預處理指令都是以
#開頭,且結尾沒有分號
2、預處理指令在**翻譯成0和
1之前執行
3、預處理指令可以出現在程式的任何位置,它的作用範圍是從它出現的位置到檔案尾。習慣上我們盡可能將預處理指令寫在源程式開頭,這種情況下,它的作用範圍就是整個源程式檔案4、
c語言提供的預處理指令主要有:巨集定義、檔案包含、條件編譯 (
1)定義格式:
#define 巨集名值
(2)作用
它的作用是在編譯預處理時,將源程式中所有"巨集名
"替換成右邊的"值
",常用來定義常量。對程式中用雙引號擴起來的字串內的字元,不進行巨集的替換操作。
#define count 5
#define kcount 5
會將count
替換為5
,雙引號內的不會替換,如:
char *name=」count」
;#undef count //
此行開始
count
這個巨集失效(3
)在編譯預處理用字串替換巨集名時,不作語法檢查,只是簡單的字串替換。只有在編譯的時候才對已經展開巨集名的源程式進行語法檢查(4
)定義乙個巨集時可以引用已經定義的巨集名
#define r 3.0
#define pi 3.14
#define l 2*pi*r
一般形式:
#define 巨集名(
引數列表
) 字串
作用:在編譯預處理時,將源程式中所有巨集名替換成字串,並且將字串中的引數用巨集名右邊引數列表中的引數替換
#define sum(v1, v2) v1+v2
int c=sum(10,11); //
將sum(10,11)
轉換為10+11,即c
值為21
int d=sum(2,3)*sum(4,5);//d
的值為19
,不是預想的
45分析:帶引數的巨集在展開時,只作簡單的字元和引數的替換,不進行任何計算操作,所以
sum(2,3)*sum(4,5)
會轉換為
2+3*4+5
,即19
,並不會先計算出
sum(2,3)
,再去乘
sum(4,5)
的值。所以定義時結果值要加小括號,引數也要加小括號。
#define sum(v1, v2) ((v1)+(v2))
#define pingfang(a) ((a)*(a))
帶引數的巨集定義,在源程式中出現的形式與函式很像。但是兩者是有本質區別的:(1
)巨集定義不涉及儲存空間的分配、引數型別匹配、引數傳遞、返回值問題(2
)函式呼叫在程式執行時執行,而巨集的替換只在編譯預處理階段進行。所以帶引數的巨集比函式具有更高的執行效率,簡單函式可以使用巨集代替。
有時我們希望程式的某一部分**只有在滿足一定條件時才進行編譯,否則不參與編譯(只有參與編譯的**最終才會被執行),這就是條件編譯。簡單的說條件編譯就是有條件的編譯某段**,
#if 條件1
//...code1...
#elif 條件2
//...code2...
#else
//...code3...
#endif
(
1)如果條件
1成立,那麼編譯器就會把
#if與
#elif
之間的code1
**編譯進去(注意:是編譯進去,不是執行),其他**不會參與編譯。而
if-else
會編譯所以語句(2
)如果條件
1不成立、條件
2成立,那麼編譯器會把
code2
**編譯進去(3
)如果條件1、
2都不成立,那麼編譯器就會把
#else
與#endif
之間的code3
編譯進去(4
)條件編譯結束後,必須在最後麵加乙個
#endif(5
)#if
和#elif
後面的條件一般是判斷巨集定義而不是判斷變數,因為條件編譯是在編譯之前做的判斷,巨集定義也是編譯之前定義的,而變數是在執行時才產生的、才有使用的意義
#if
和#elif
後面的條件不僅僅可以用來判斷巨集的值,還可以判斷是否定義過某個巨集。比如:
#if defined(max)
// ...code...
#endif
如果前面已經定義過
max這個巨集,就將
code
編譯進去。它不會管
max的值是多少,只要定義過
max,條件就成立。
條件也可以取反:
#if !defined(max)
//...code...
#endif
如果前面沒有定義過
max這個巨集,就將
code
編譯進去。4、
#ifdef
和#ifndef
的使用#ifdef
的使用和
#if defined()
的用法基本一致
#ifdef max
//...code...
#endif
如果前面已經定義過
max這個巨集,就將
code
編譯進去。
#ifndef
又和#if !defined()
的用法基本一致
#ifndef max
//...code...
#endif
如果前面沒有定義過
max這個巨集,就將
code
編譯進去。
#include #define max 10
int main ()
在第
2行定義了乙個巨集
max,注意第5到第
11行的條件編譯語句。由於
max為
10,所以
#elif
的條件成立,第
8行**將會被編譯進去,其實編譯預處理後的**是這樣的:
int main ()
常見的#include
就是檔案包含,它是拷貝
<>或」」
內的檔案到
#include
處#include
<
檔名》
用於系統自帶的檔案,直接在
c語言庫函式的標頭檔案所在的目錄中尋找檔案
#include
"檔名
"用於自定義的檔案,系統會先在源程式當前目錄下尋找,若找不到,再到作業系統的
path
路徑中查詢,最後才到
c語言庫函式標頭檔案所在目錄中查詢(1
)#include
指令允許巢狀包含,比如
a.h包含
b.h,
b.h包含
c.h,但是不允許迴圈包含,比如
a.h
包含b.h
,b.h
包含a.h。(
2)使用
#include
指令可能導致多次包含同乙個標頭檔案,這樣編譯效率會降低,利用條件編譯可防止標頭檔案重複包含
#dendef
檔名_h
#define
檔名_h//
定義乙個空的巨集
//函式宣告
#endif
兩個.h
檔案內的巨集名不可以相同,否則可能導致另乙個標頭檔案不被編譯,所以巨集名以檔名
_h命名
例如:#dendef one_h
#define one_h
void one();
#endif
當我們第一次
#include "one.h"
時,因為沒有定義
one_h
,所以條件成立,所以會拷貝
one.h
檔案,會定義
one_h
這個巨集,宣告
one函式。當第二次
#include"one.h"
,因為已經定義過
one_h
這個巨集,所以條件不成立,直接跳到
#endif
,結束條件編譯。所以防止了
one.h
的內容被重複包含。
黑馬程式設計師 C語言之預處理命令
asp.net unity開發 net培訓 期待與您交流!1.所有的預處理指令都是以 開頭 2.預處理指令分3種 1 巨集定義 2 條件編譯 3 檔案包含 3.預處理指令在 翻譯成0和1之前執行 4.預處理的位置是隨便寫的 5.預處理指令的作用域 從編寫指令的那一行開始,一直到檔案結尾,可以用 un...
黑馬程式設計師 C語言預處理指令
asp.net unity開發 net培訓 期待與您交流!1.預處理指令,預處理指令分3種 1.1 巨集定義 1.2 條件編譯 1.3 檔案包含 2.預處理指令不會被編譯,它只會在程式被編譯之前給替換掉 2.1 不帶引數的巨集 define pi 3 一般巨集定義都是全部大寫 int a pi 在程...
黑馬程式設計師 C語言之迴圈結構
asp.net unity開發 net培訓 期待與您交流!今天看的是c語言的迴圈結構,c語言中乙個很重要的部分也就是迴圈結構。他分為幾個部分,乙個是for迴圈,while迴圈,do while迴圈。下面就乙個乙個講解下迴圈結構。for迴圈 for 語句1 條件 語句2 語句1 初始化語句 語句2 增...