C語言的預處理詳解

2021-08-21 12:29:49 字數 3434 閱讀 3475

#include

這裡就使用了預處理,引入標頭檔案。同時在檔案開頭我們常見的#define ,#ifdef,#pragma之類的都屬於預處理。

那麼,我們在此先提出幾個問題:

1.預處理是c語言的一部分嗎?

2.包含#號的都是預處理嗎?

3.預處理指令後面是不是都不需要加「;」呢?

看完本文,相信你就會得出答案。

首先我們來了解一下ansi標準定義的c語言預處理指令都有哪些?

除了這些之外還有幾個沒有出現在表中的巨集:

_line_:正在編譯的檔案的行號

_file_:正在編譯的檔案的名字

_date_:編譯時刻的日期字串

_time_:編譯時刻的時間字串

_stdc_:判斷該程式是否為標準的c程式

若編譯器非標準的,則上述巨集有可能支援部分或根本不支援。在此我們將就表中的預處理進行講解。

#define非常方便,所以我們當然都喜歡用它。define常用來定義常量和字串常量。例如,#define pi 3.1415926

在後續的**中,你都可以用pi來代替這一串數字了。而且就算我要求pi的精度再提高一些那也沒有關係,我們只要在define處修改一下就可以了。若是沒有使用巨集定義,你就要在**中處處尋找3.1415926然後去修改,是不是感覺痛苦不堪呢?

雖然它可以給我們帶來許多便利,但是在使用它的時候一定要小心再小心,它也經常會在你不注意的時候讓你犯下錯誤。例如下面這段**。

#define pchar char*

pchar p1,p2;

這段**有什麼問題呢?編譯並不會出錯,而且p1確實是char*型別。但是!

照理來說指標再取位址就要用char**型別的變數來接收,所以char**a = &p1這句**並無問題。

但是char**b = &p2提示了錯誤:char*型別的值不能用char**來接受。也就是說我們的p2它竟然是乙個char型別,而並不是char*型別變數?

所以像這種沒有辦法一下就發現的錯誤才是最恐怖的錯誤。像這種情況我還是建議大家乙個個的定義變數。實在不行可以使用typedef,不會出現這種問題。

我們還可以用define定義字串,一般用於路徑:

#define file_path e:\folder1\1.txt

這個預處理命令也就是undefine的意思,即撤銷巨集定義。也就是說巨集定義的生命週期從#define開始到#undef結束。

這是我們最常見的詞語了。在編譯乙個程式的時候,首先第一句話就是#include 啦。它同樣也非常重要,是將多個原始檔連線成乙個原始檔進行編譯,結果就生成乙個目標檔案(obj)。常見有兩種形式:

1.include

用尖括號括起來的標頭檔案一般都是系統自帶的,表示系統將在指定的路徑進行尋找。

2.include "***.h"

雙引號一般則用於我們自己編寫的標頭檔案,系統也會優先在當前目錄中查詢。如果找不到指定檔名的檔案就會和形式1一樣在指定的路徑進行尋找。

平常寫**過程中,我們為了實現分支結構會經常使用if else結構,在預處理同樣也有類似的功能,即條件編譯。我們可以按照不同的條件去編譯不同的部分,這對程式的移植和除錯有著巨大的幫助。條件編譯主要有以下兩種形式。

1.#ifdef 識別符號1  &&  #ifndef 識別符號2

//code1

#else

//code2

#endif

這一段就是經典的條件編譯。如果定義了識別符號1(或如果沒有定義(ifndef)識別符號2),執行**段code1;否則執行code2.

要注意的是#ifdef或#ifndef需要和#endif對應。

2.#if 常量表示式

//code1

#else

//code2

#endif

這段則無限接近我們日常使用的if else了。同樣要注意endif。

除此之外還有乙個#elif,即是elseif,形成if else_if 階梯狀語句,可以進行多種編譯選擇。

它的作用人如其名,是用來提示錯誤的,編譯程式時如果遇到#error就會生成乙個編譯錯誤提示資訊並停止編譯。關於提示的錯誤資訊都是系統定義好的,這裡不再介紹,請查詢相關資料。

#pragma可能是所有預處理指令中最複雜的那個了,因為它可以跟很多引數,而這些引數實現的功能也都大相徑庭。當然了,越複雜功能也就越強大,這裡挑幾個常見的引數進行講解。

1.#pragma once

在標頭檔案的最開始處加上這句話,就可以避免標頭檔案的重複引用(include)。它的作用就是保證每個標頭檔案只編譯一次,再加入同名的標頭檔案也沒有關係(反正也不編譯,且不會報錯)。

2.#pragma message

在我們編寫程式時,有時一旦定義了許多巨集則有可能忘記了某個關鍵的巨集是否正確的設定了。這時只需要使用這條指令就可以一目了然。

具體用法:

編譯時的控制台將顯示引號中的內容。

當出現這條語句代表預編譯標頭檔案到此為止,後面的將不再參與預編譯。通常這樣做用來指定編譯優先順序,同時也可以加快鏈結的速度(一次編譯太多頭檔案可能會佔很多磁碟空間)。

4.#pragma warning

此指令用於和warning有關的操作(即非致命程式設計錯誤的警告)。

具體示例:

#pragma warning (disable:4707)     //遮蔽4707警告

#pragma warning (once:4706)         //只顯示一次4706警告

#pragma warning (error:164)           //將164號警告當作乙個錯誤。

也可以三合一寫成:#pragma warning (disable:4707;once:4706;error:164)

5.#pragma comment

該指令用於導入庫。

例如:#pragma comment (lib,"user32.lib")

將user32.lib 庫檔案匯入本工程中。

6.#pragma pack

本知識涉及到記憶體對齊,詳細講解請看我的另一篇部落格《記憶體對齊》。

C語言預處理

c語言中編譯預處理的三種形式的命令 巨集定義,檔案包含,條件編譯命令。1 巨集定義主要是 define,undef 如下 define pi 3.1415926 不帶引數的巨集定義 define max a,b a b?a b 帶引數的巨集定義 說明 巨集定義在c語言與c 語言中是相通的。下面舉例說...

C語言預處理

預處理 系統自動自動呼叫預處理程式對程式中 號開頭的預處理部分進行處理,處理完畢後可以進城源程式的編譯階段。預定義 一些預定義符號 常用於除錯 file 正在預編譯的源檔名 line 當前行號 只有這個是整數常量,其他是字串常量 function 當前所在函式名 date 當前日期 time 當前時...

c語言預處理

預處理可以包含 1 巨集定義指令 2 標頭檔案包括指令 3 條件編譯指令 4 編譯程式可以識別的特殊符號 巨集定義 define undef 檔案包含 include 條件編譯 if ifdef else elif endif等 其他 line error program等 注意事項 1 在c語言中...