二:檔案包含(#include)
三:條件編譯
所謂的預編譯指令,就是指在「編譯c語言**」之前,對原始碼進行處理的指令。
預編譯指令,不是c語言。
c語言中的預編譯指令,都以#開頭。
實際上,編譯器的編譯過程,是:
cl /c /p first.c
cl /c /fas first.c
c語言的預處理主要有三個方面的內容:
巨集將是我們學習的第乙個預編譯指令。巨集的本質是查詢替換
。
#define mymsg "hello, world"
#define myadd(a,b) a+b
#define mymul(a,b) a*b
int main(int argc, char* ar**)
因為巨集是直接查詢替換,所以使用不當,容易造成問題。一定要多打括號。
以下為微軟某個庫函式的的定義
#define max(a,b) (((a) > (b)) ? (a) : (b))
有參巨集的引數,若有乙個#,那麼會將引數字串化
如:
#define mymacro(a) "hello: "#a
int main(int argc, char* ar**)
其結果為:
可以看到成功完成了替換
注意
在vs中,優化了字串的統計,如果出現
"hello""world"
將被優化為
"helloworld"
如:如何快速宣告一系列有規律的函式?
int myaddint(int x, int y);
double myadddouble(double x, double y);
我們期望
declaremyfun(type);
main()
以下的宣告是錯誤的
#define declaremyfun(type) type myaddtype(type x, type y)
declaremyfun(int);
declaremyfun(double);
其宣告的結果為:
int myaddtype(int x, int y);
double myaddtype(double x, double y);
我們如果需要在乙個token特別強調它的某部分是巨集引數,我們就需要使用##。
#define declaremyfun(type) type myadd##type(type x, type y)
declaremyfun(int);
declaremyfun(double);
int main(int argc, char* ar**)
乙個檔案包含另乙個檔案的內容(即查詢、複製、貼上)
格式:
#include "檔名"
或
#include 《檔名》
編譯時以包含處理以後的檔案為編譯單位,被包含的檔案是原始檔的一部分。
編譯以後只得到乙個目標檔案.obj
被包含的檔案又被稱為「標題檔案」或「頭部檔案」、「標頭檔案」,並且常用.h作副檔名。
修改標頭檔案後所有包含該檔案的檔案都要重新編譯
標頭檔案的內容除了函式原型和巨集定義外,還可以有結構體定義,全域性變數定義
注意
類似於if…else語句,可以根據巨集是否定義,來決定某段**是否需要編譯
#ifdef 識別符號
//程式段1
#else
//程式段2
#endif
或
#ifdef
//程式段1
#endif
#ifndef 識別符號
#define 標識1
//程式段1
#endif
#if 表示式1
//程式段1
#elif 表示式2
//程式段2
#elif 表示式n
//程式段n
#else
//程式段n+1
#endif
如#pragma的一些命令的實現
介紹:#pragma為編譯器提供了一種在不同機器和作業系統上編譯以保持c和c++完全相容的方法。#pragma是由機器和相關的作業系統定義的,通常對每個編譯器來說是不同的。
示範#pragma的原理
準備兩個標頭檔案
myhead1.h
extern int nvalue;
myhead2.h
#include "myhead1.h"
void myfun();
我們再包含它們
main.cpp
#include "myhead1.h"
#include "myhead2.h"
int main(int argc, char* ar**)
這就相當於
extern int nvalue;
extern int nvalue;
void myfun();
int main(int argc, char* ar**)
可以看到有些標頭檔案被重複包含。
輕則降低效率,重則編譯出錯。
我們可以使用條件編譯,解決這個問題。
#ifndef head
#define head
extern int nvalue;
#endif
myhead2.h
#ifndef head
#define head
extern int nvalue;
void myfun();
#endif
這就是#pragma once
的實現原理,即標頭檔案只被包含一次。
使用條件編譯可以使目標程式變小,執行時間變短。
預編譯使問題或演算法的解決方案增多,有助於我們選擇合適的解決方案。
此外,還有布局控制:#pragma,這也是我們應用預處理的乙個重要方面,主要功能是為編譯程式提供非常規的控制流資訊。
c c 中的預編譯指令總結
預處理指令提供按條件跳過原始檔中的節 報告錯誤和警告條件,以及描繪源 的不同區域的能力。使用術語 預處理指令 只是為了與 c 和 c 程式語言保持一致。在 c 中沒有單獨的預處理步驟 預處理指令按詞法分析階段的一部分處理。預處理器的主要作用就是把通過預處理的內建功能對乙個資源進行等價替換,最常見的預...
c c 中的預編譯指令總結
預處理指令提供按條件跳過原始檔中的節 報告錯誤和警告條件,以及描繪源 的不同區域的能力。使用術語 預處理指令 只是為了與 c 和 c 程式語言保持一致。在 c 中沒有單獨的預處理步驟 預處理指令按詞法分析階段的一部分處理。預處理器的主要作用就是把通過預處理的內建功能對乙個資源進行等價替換,最常見的預...
C 預編譯指令
下面對c 中的預編譯指令進行介紹 1.define和 undef 用法 define debug undef debug define告訴編譯器,我定義了乙個debug的乙個符號,他類似乙個變數,但是它沒有具體的值,可以將它看為乙個符號而已。undef就是刪除這個符號的定義。如果符號debug沒定義...