回覆列表
  • 1 # 年輪978865

    C語言源程式中允許用一個識別符號來表示一個字串,稱為“宏”。被定義為宏的識別符號稱為“宏名”。在編譯預處理時,對程式中所有出現的宏名,都用宏定義中的字串去代換,這稱為宏替換或宏展開。

    宏定義是由源程式中的宏定義命令完成的。宏替換是由預處理程式自動完成的。

    1 .無參宏定義

    無參宏的宏名後不帶引數。其定義的一般形式為:

    #define 識別符號 字串

    #define 識別符號 字串

    其中,“#”表示這是一條預處理命令(以#開頭的均為預處理命令)。“define”為宏定義命令。“識別符號”為符號常量,即宏名。“字串”可以是常數、表示式、格式串等。

    宏定義用宏名來表示一個字串,在宏展開時又以該字串取代宏名。這只是一種簡單的文字替換,預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被宏展開後的源程式時發現。

    注意理解宏替換中“換”的概念,即在對相關命令或語句的含義和功能作具體分析之前就要進行文字替換。

    【例1】定義常量:

    #defineMAX_TIME 1000

    若在程式裡面寫if(time < MAX_TIME){.........},則編譯器在處理該程式碼前會將MAX_TIME替換為1000。

    注意,這種情況下使用const定義常量可能更好,如const int MAX_TIME = 1000;。因為const常量有資料型別,而宏常量沒有資料型別。編譯器可以對前者進行型別安全檢查,而對後者只進行簡單的字元文字替換,沒有型別安全檢查,並且在字元替換時可能會產生意料不到的錯誤。

    宏名一般用大寫字母表示,以便於與變數區別。宏定義末尾不必加分號,否則連分號一併替換。宏定義可以巢狀。

    可用#undef命令終止宏定義的作用域。

    使用宏可提高程式通用性和易讀性,減少不一致性,減少輸入錯誤和便於修改。如陣列大小常用宏定義。預處理是在編譯之前的處理,而編譯工作的任務之一就是語法檢查,預處理不做語法檢查。宏定義寫在函式的花括號外邊,作用域為其後的程式,通常在檔案的最開頭。字串" "中永遠不包含宏,否則該宏名當字串處理。

    宏定義不分配記憶體,變數定義分配記憶體。

    2. 帶參宏定義

    C語言允許宏帶有引數。在宏定義中的引數稱為形式引數,在宏呼叫中的引數稱為實際引數。

    對帶引數的宏,在呼叫中,不僅要宏展開,而且要用實參去代換形參。

    帶參宏定義的一般形式為:

    #define 宏名(形參表) 字串

    #define 宏名(形參表) 字串

    在字串中含有各個形參。

    帶參宏呼叫的一般形式為:

    宏名(實參表);

    在宏定義中的形參是識別符號,而宏呼叫中的實參可以是表示式。

    在帶參宏定義中,形參不分配記憶體單元,因此不必作型別定義。而宏呼叫中的實參有具體的值,要用它們去代換形參,因此必須作型別說明,這點與函式不同。函式中形參和實參是兩個不同的量,各有自己的作用域,呼叫時要把實參值賦予形參,進行“值傳遞”。而在帶參宏中只是符號代換,不存在值傳遞問題。

    【例3】

    #define INC(x) x+1 //宏定義

    y = INC(5); //宏呼叫

    #define INC(x) x+1 //宏定義

    y = INC(5); //宏呼叫

    在宏呼叫時,用實參5去代替形參x,經預處理宏展開後的語句為y=5+1。

  • 中秋節和大豐收的關聯?
  • 寶寶睡搖床好不好?