C小白Jeff頭禿的第九天 笑裡藏刀的預處理指令

2021-10-08 22:05:47 字數 2285 閱讀 9395

程式設計師所編寫的**並不能直接被編譯器編譯,需要一段程式把翻譯一下。

翻譯的過程叫預處理,被翻譯的**叫預處理指令,以#開頭的都是預處理指令。

gcc -e code.c 把預處理的結果顯示在螢幕上

gcc -e code.c -o code.i 把預處理的結果儲存到code.i檔案中

#include <> 從系統指定的路徑查詢並匯入標頭檔案

#include "" 先從當前路徑查詢如果沒有再從系統指定的路徑查詢並匯入標頭檔案。

作業系統通過設定環境變數,編譯引數-i 來指定標頭檔案查詢路徑,或者設定編譯器引數 -i /path

巨集常量:#define max 100
優點:提高可擴充套件性(替換)、提高可讀性(替換成有意義的**)、提高安全性高(不可修改)、還可用在case後(與switch語句配合使用)。

注意:一般巨集名全部大寫,末尾不要有分號;不能直接換行(可以使用換行符續行)

預定義的巨集:

__func__ 獲取函式名

__file__ 獲取檔名

__line__ 獲取當前行號

__date__ 獲取當前日期

__time__ 獲取當前時間

巨集函式:其實就是帶引數的巨集
不是真正的函式,不檢查引數型別,沒有傳參,沒有返回值。

#define dfunc(a,b,c) (a+b+c)/3

1、把**使用到巨集函式替換為,巨集函式後面的**。

2、把巨集函式**中使用的引數替換為呼叫者提供的引數。

注意:定義巨集常量和巨集函式不能換行,可以使用續行符\,也可以使用大括號來保護**。

由於**所處位置、引數不同導致巨集有不同的功能,這種巨集的二義性。

如何避免二義性:巨集函式整體要加小括號(如果換行要加大括號),每個引數都要加小括號。

注意:容易出現選擇題,如:那個巨集可能有二義性。

注意:使用巨集函式時提供帶自變運算子的變數作為引數。

注意:如果是普通型別,它們功能沒有區別。

#define intp int*

intp p1,p2,p3; // p1是指標,p2,p3是int型別變數

typedef int* intp;

intp p1,p2,p3; // p1,p2,p3都是指標

巨集函式與普通的函式區別?

它們是什麼

其實就是帶引數的巨集不是真正的函式,不檢查引數型別,沒有傳參,沒有返回值。

有什麼不一樣

函式 返回值 型別檢查 安全 壓棧、出棧 速度慢 跳轉

巨集函式 運算結果 通過 危險 替換 速度快 冗餘

優缺點:

#   把引數變成字串(輸出帶引號)

## 合併兩個引數變成識別符號。(連線)

根據條件決定是否參生成**或者生成那部分帶碼。

三種不同形式:

1、版本控制
#if 

#elif

#else

#endif

#ifndef	filename

#define filename

#endif

系統位數判斷

x86 64 i386

#ifdef debug

#define debug(...) printf(__va_args__)

#else

#define debug(...)

#endif

#define error(...) fprintf(stdout,"%s:%s:%d %s %m %s %s\n",__file__,__func__ ,__line__,

__va_args__,__date__,__time__)

預處理指令為何笑裡藏刀?c提供的預處理功能常用的主要有一下3種:

1、巨集定義;二義性。巨集定義是用巨集名表示乙個字串,在巨集展開時又將該字串取代巨集名,字串可以是任何字元,也可以是常數,也可以是表示式。其中,預處理程式不對巨集定義做任何檢查,如果巨集定義出現錯誤,只能在編譯時被巨集展開後的源程式發現錯誤。

2、檔案包括;.乙個include命令只能指定乙個被包含檔案,若有多個檔案需要包含,則需要用多個include命令。檔案包含允許巢狀,即在乙個被包含的檔案中又可以包含另乙個檔案。

3、條件編譯:上文已經介紹。

學習的第九天

如題,又是安裝的一天 又到了熟悉的連線環節,至於為什麼每次使用centos7虛擬機器都要進行這看似不必要的部分。原因當然是為了之後更方便。要知道centos7系統 圖形化除外 中是不可以進行複製貼上的,但要在centos7中執行各種命令都是要輸入長長指令,而作為我這種菜鳥,肯定不能盲打,but看一眼...

第九天C高階 malloc calloc free

典型的錯誤的對陣列的宣告 int max stage intmain 錯誤1 變數的 宣告 應該放在 語句 的前面 錯誤2 宣告的陣列元素個數不是常量表示式 正確的使用動態的儲存空間 malloc calloc free include.void calloc size t nmemb,size t...

疫情學習第九天 C

我還在學c 隔一天學一次,我喜歡在這個房間裡面學習。4.2 物件的初始化和清理 4.2.1 建構函式 初始化 和析構函式 清理 由編譯器自動呼叫,如果自己不提供,編譯器會提供,編譯器提供的是函式是空實現。建構函式 進行初始化和清理 建構函式,沒有返回值不用寫void 函式名與類名相同 建構函式可以有...