C語言預處理命令分類和工作原理

2021-01-07 酷扯兒

本文轉載自【微信公眾號:strongerHuang,ID:strongerHuang】經微信公眾號授權轉載,如需轉載與原文作者聯繫

C語言編程過程中,經常會用到如 #include、#define 等指令,這些標識開頭的指令被稱為預處理指令,預處理指令由預處理程序(預處理器)操作。

相比其他程式語言,C/C++ 語言更依賴預處理器,故在閱讀或開發 C/C++ 程序過程中,可能會接觸大量的預處理指令。

1

預處理指令及分類

C/C++ 程序中的原始碼中包含以 # 開頭的各種編譯指令,這些指令稱為預處理指令。預處理指令不屬於 C/C++ 語言的語法,但在一定意義上可以說預處理擴展了 C/C++。

ANSI C 定義的預處理指令主要包括:文件包含、宏定義、條件編譯和特殊控制等 4 類。

1. 文件包含

文件包含:#include 是 C 程序設計中最常用的預處理指令。例如,幾乎每個需要輸入輸出的 C 程序,都要包含 #include<stdio.h> 指令,表示把 stdio.h 文件中的全部內容,替換該行指令。

包含文件的格式有 #include 後面跟尖括號 <> 和雙引號 "" 之分。兩者的主要差別是搜索路徑的不同。

尖括號形式:如 #include<math.h>,預處理器直接到系統目錄對應文件中搜索 math.h 文件,搜索不到則報錯。系統提供的頭文件一般採用該包含方式,而自定義的頭文件不能採用該方式。

雙引號形式:如 #include"cal.h",首先到當前工作目錄下查找該文件,如果沒有找到,再到系統目錄下查找。包含自定義的頭文件,一般採用該方式。雖然系統頭文件採用此方式也正確,但浪費了不必要的搜索時間,故系統頭文件不建議採用該包含方式。

2.宏定義

宏定義:包括定義宏 #define 和宏刪除 #undef。

以 #define 開頭,可以定義無參數宏和帶參的宏定義。程序中經常使用無參宏定義來定義符號常量。例如:

#define PI 3.1416 //定義無符號宏,或定義符號常量 PI

#undef 表示刪除已定義的宏,例如:

#undef PI //刪除前面該宏的定義

3.條件編譯

條件編譯:主要是為了有選擇性地執行相應操作,防止宏替換內容(如文件等)的重複包含。

常見的條件編譯指令有 #if、#elif、#else、#endif、#ifdef、#ifndef。

4.特殊控制

特殊控制:ANSI C 還定義了特殊作用的預處理指令,如 #error、#pragma。

#error:使預處理器輸出指定的錯誤信息,通常用於調試程序。

#pragma:是功能比較豐富且靈活的指令,可以有不同的參數選擇,從而完成相應的特 定功能操作。調用格式為:#pragma 參數。

其中,參數可以有 message 類型、code_seg、once、warning、pack 等。通常使用如下的預處理指令來設定內存以 n 字節對齊方式。

#pragma pack (n) //其中 n 稱為對齊係數,取 1、2、4、8...

2

預處理器及其工作原理

C預處理器(C Pre-Processor)也常簡寫為 CPP,是一個與 C 編譯器獨立的小程序,預編譯器並不理解 C 語言語法,它僅是在程序源文件被編譯之前,實現文本替換的功能。

目前預編譯器巳集成到集成開發環境中,一般並沒有執行預處理操作的選項,而包含在了編譯操作中,即選擇編譯操作時,首先調用的是預處理器,處理源程序文件中的預處理指令,預處理器的輸出再送給編譯器,編譯器從 C 語言語法角度檢查程序是否正確,如果正確,則生成目標代碼文件或機器指令文件。

C 預處理器及 C 編譯器的執行順序及輸入輸出文件類型,如圖所示:

免責聲明:本文部分素材來源網絡,版權歸原作者所有。如涉及作品版權問題,請與我聯繫刪除。

相關焦點

  • C/C+編程筆記:C語言預處理命令是什麼?不要以為你直接寫#就行!
    很多小夥伴在自己寫代碼的時候,已經多次使用過#include命令。使用庫函數之前,應該用#include引入對應的頭文件。其實這種以#號開頭的命令稱為預處理命令。
  • C語言的那些小秘密之預處理
    預處理是C語言的一個重要知識點,它能改善程序設計的環境,有助於編寫易移植、易調試的程序。因此,我們有必要掌握好預處理命令,在自己編程的時候靈活的使用它,使得編寫的程序結構優良,更加易於調試和閱讀。接下來我儘可能的把預處理中重要知識點向讀者講解清楚,使讀者能夠在自己以後編程的過程中熟練的使用預處理命令。
  • 快速上手系列-C語言之預編譯命令、宏定義及條件編譯
    上一篇寫了C語言中變量的存儲類別,提到普通局部變量、普通全局變量和靜態局部變量及靜態全局變量,這裡簡單了解一下C語言的預編譯命令、宏定義和條件編譯。預編譯命令(預編譯處理--->編譯---->彙編--->連接)1、預處理:預處理是C語言的一個重要功能,如文件包含、常量定義都屬於預處理命令,C語言提供的預處理功能主要有以下三種:1)文件包含 #include2)宏定義 #define3)條件編譯 #if #endif4)防止頭文件重複包含2、文件包含處理
  • C語言中的 define預處理指令老手都是這樣用,你全都掌握了嗎?
    C語言有許多預處理命令,#define是其預處理命令之一。所有預處理命令以「#」號開頭,如包含命令#include,標準錯誤指令#error,#pragma指令等。#define指令用於宏定義,可以提高原始碼的可讀性,為編程提供方便,一般放在源文件的前面部分。本文簡要總結#define指令的多種用法及其注意事項。
  • (宇宙最強C/C++編譯器)樂創DIY C語言講義​——2.6 GCC的使用
    GCC之前簡單介紹過,它是用來開發GNU C語言的編譯器,這個GNU C說的通俗易懂一些就是Linux底下的C語言開發,之前我們說了,目前市面上的C語言編譯器,要麼是完全不區分C語言和C++的MSVC,要麼是老到掉牙的Borland C,但就Borland C來說吧,它支持的最多也就C89,而且可能還不完全支持,因此在開發的時候會很麻煩,也不建議用。
  • C語言#include命令尖括號和雙引號的區別
    接上文:C語言的預處理指令介紹#include 是C語言預處理命令的一種,叫做文件包含命令,用來引入對應的頭文件(.h文件
  • 以Linux系統上的gcc為例,解密C語言編譯背後的全過程!
    在這個網際網路時代,很多人都選擇了計算機專業,而只要是計算機專業的小夥伴,可能都會學C語言,但是大家是否都清楚C語言編譯的完整過程呢,今天我就帶著大家一起來做個解密吧。 C語言相對於彙編語言是一種高級語言,要想在系統上運行,需要通過編譯器把它轉換成機器能夠讀懂的可執行的代碼。
  • Linux、C/C++學習路線圖、C語言學習路線
    《5天20篇CSDN精選博文帶你掌握系統化學習方法》專欄將挑選有關「系統化學習方法」的20篇優質文章,幫助大家掌握更加科學的學習方法~在這裡,你將收穫:快速掌握系統化學習的理論基礎,探究本質和原理學會將已有知識體系化,形成自己的知識圖譜,離學霸更近一步系統化學習必備工具推薦與使用方法教學,實現高效學習嘗試將系統化學習思維運用於工作
  • CSS 預處理語言less快速入門
    Less 是一門 CSS 預處理語言,它擴充了 CSS 語言,增加了諸如變量、混合(mixin)、函數等功能,讓 CSS 更易維護、方便製作主題
  • 《C語言入門指南》中篇
    此為中篇,涵蓋知識點為:函數、預處理命令、數組、排序和查找,中篇全文共計12000餘字,適用初學者入門C語言,非初學者也可以通過本文複習C語言相關知識點,強化記憶!十三發布這篇筆記也是為了複習C語言!本文已收錄到GitHub[1]開源倉庫【Ye13[2]】,點擊閱讀原文即可跳轉,進行star!
  • Linux GCC常用命令
    經過了這麼多年的發展,GCC 已經不僅僅能支持 C 語言;它現在還支持 Ada 語言、C++ 語言、Java 語言、Objective C 語言、Pascal 語言、COBOL語言,以及支持函數式編程和邏輯編程的 Mercury 語言,等等。而 GCC 也不再單只是 GNU C 語言編譯器的意思了,而是變成了 GNU Compiler Collection 也即是 GNU 編譯器家族的意思了。
  • C/C++學習----使用C語言代替cmd命令、cmd命令大全
    昨天的文章「CPU阿甘」大家是不是還沒看呢,原作者可是在IBM工作的劉欣,有著15年工作經驗了,寫的文章真心給力,沒看過的趕緊在公眾號下回復「44」便可以查看那篇文章了
  • 【本質】你知道C語言編譯的過程嗎?
    使用預處理器把源文件test.c經過預處理生成test.i文件,預處理用於將所有的#include頭文件以及宏定義替換成其真正的內容。預處理的命令為:gcc -E test.c -o test.i上述命令中-E是讓編譯器在預處理之後就退出,不進行後續編譯過程;-o是指定輸出文件名。
  • iOS編譯過程的原理和應用
    前言一般可以將程式語言分為兩種,編譯語言和直譯式語言。像C++,Objective C都是編譯語言。編譯語言在執行的時候,必須先通過編譯器生成機器碼,機器碼可以直接在CPU上執行,所以執行效率較高。像JavaScript,Python都是直譯式語言。直譯式語言不需要經過編譯的過程,而是在執行的時候通過一個中間的解釋器將代碼解釋為CPU可以執行的代碼。
  • 入門C語言!
    也許有很多同學想學習C語言,卻不知道從什麼地方入手。或者有一些同學,學了一些基礎,太簡單的覺得枯燥無趣,有點複雜的又靜不下心來細細琢磨,也就是所謂的瓶頸時期,如果過了這個時期,C語言的學習就會順暢很多,高度也會大幅度提升。
  • 《邊學邊用攻破C語言》第17集 宏定義define的用法
    《邊學邊用攻破C語言》是專門為單片機初學者準備的C語言基礎視頻教學課程,是科技老頑童
  • 在Stata中編寫估計命令:編寫C語言插件
    這篇文章演示了如何用其他語言(如C,C 或Java)編寫的代碼插入到Stata中。這種技術被稱為Stata編寫插件或編寫動態連結庫(DLL)。本文中,在C語言中編寫一個插件,它實現了mymean11.ado中mymean_work()執行的計算,在文章在Stata中編寫估計命令編寫插件中討論過。
  • C語言編寫程序求水仙花數
    C語言編寫程序求水仙花數水仙花數是一個數學問題,其實質是一個三位數,個位數的立方加十位數的立方加百位數的立方之和等於這個三位數本身。例如153=1*1*1+5*5*5+3*3*3,即153=1+125+27。
  • C語言入門
    這些都可以用來編寫C語言程序。2、什麼是編譯器通過編輯器寫出的代碼只是源程序的文本文件,必須經過編譯之後才可以在電腦上運行。常用的編譯器有:microsoft C++Compiler、gcc等。3、什麼是集成開發環境(IDE)集成開發環境就是為程序開發提供的環境應用軟體,裡面集成了編輯器和編譯器。
  • 快速指南:使用OpenCV預處理神經網絡中的面部圖像的
    因此在將圖像輸入神經網絡之前,需要經過一個預處理階段,以便達到更好的分類效果。圖像預處理通常來說非常簡單,只需執行幾個簡單的步驟即可輕鬆完成。但為了提高模型的準確性,這也是一項非常重要的任務。對於這些問題,我們可以使用OpenCV完成:一個針對(實時)計算機視覺應用程式的高度優化的開源庫,包括C ++,Java和Python語言。