1.預處理規則
文件包含
宏定義
條件編譯
2.預處理器的主要工作:
1、文件包含
2、宏定義替換
3、取捨條件編譯
3.預處理通用規則
指令都以#開始
在指令的符號間可有任意數量的空格或tab
通常指令在第一個換行符處結束,末尾不出現‘;’
指令可出現在程序任何地方,但通常#define,#include指令出現在文件開始
註釋與指令可出現在同一行
宏名一般都以大寫字母表示
4.預處理器的作用:
預處理器相當於編輯工具,通過處理’#’開頭的預處理指示,重新編輯C的源文件,過濾掉對人類有用的信息,留下對機器有用的信息,保留原始的字節流, 使代碼更精練,編譯、執行效率更高。
註釋—對程序閱讀者有用,對機器無用,預處理時會把註釋去掉,還有:空行,空格,縮進。
經過預處理後把源代碼還原成原始的字節流,這種字節流對機器來講處理起來比較快。
5.宏定義只進行簡單替換(預處理器只進行編輯處理),不進行正確性檢查(編譯器才進行語法檢查)
6.變量式宏定義
語法:#define 宏名替換列表
在代碼中所有的宏名都會被替換爲替換列表中的內容 不要在宏定義末尾添加’;’
7.變量式宏定義的好處:
1、程序更易讀
2、程序更易修改
3、控制條件編譯
8.宏定義的作用域:
從宏定義的地方開始到文件結束,和全局變量的作用域類似,但全局變量可以通過extern關鍵字在其他模塊中聲明來將全局變量導出到其他的文件中,而宏定 義不可以。
9.取消宏定義:#undef
10.函數式宏定義
函數式(帶參數)宏定義
語法:#define 宏名(x1,x2,…,xn) 替換列表
參數x1、x2…xn可以在替換列表中出現多次
在帶參數的宏定義當中一定要毫不吝嗇地加(),來人爲地控制優先級和接合性
11.宏定義中的續行符?\?
通常#開頭的指令只佔一行,若指令較長可使用’\’進行續行,要求’\’後緊跟換行符
12.帶參數的宏和函數的區別:
1、宏是預處理的概念,而函數是程序執行時的概念
2、宏不會檢查參數,函數會檢查參數
3、宏不允許遞歸,函數可以遞歸
4、宏可能會對參數進行多次計算
13.帶參數的宏和函數的優缺點:
1、宏不會檢查參數,函數會檢查參數
2、帶參數的宏執行時稍微快些,不需要像函數似地進行參數壓棧、保護上下文等操作
3、宏相比較於函數在空間上會浪費
宏以空間換時間,但不進行參數檢查往往導致嚴重的問題。
14.內聯函數:inline
內聯函數是函數不是宏
集合了函數及宏的優點,既進行參數檢查又提高了運行速度(不需要進行參數壓棧、保護上下文)。宏不會檢查參數,函數會檢查參數
通常代碼實現簡短的函數會被定義爲內聯函數:
1、沒有遞歸
2、沒有循環及複雜的條件分支
3、代碼比較少
15.文件包含的作用
通常工程文件都由若干個文件組成,文件間信息共享(函數的相互調用、外部變量、宏定義、類型定義的共享)需要通過#include 頭文件實現。
16.<>:在默認路徑下搜索頭文件/usr/include/
:用戶指定的路徑下搜索:
1、表示當前路徑
2、表示用戶指定路徑
17.頭文件可以包含:
函數的聲明
全局變量的聲明
宏定義
類型的定義
嵌套包含頭文件
18.條件編譯:根據預處理器所執行的測試結果來包含或排除程序的片段。#if , #endif, #ifdef, #ifndef, #elif, #else 運算符:defined
運算符defined:應用於標識符時,測試某個宏是否被定義過,定義過返回1,否則返回0,defined通常與#if指令結合使用,
19.條件編譯的三種基本形式:
1:#if 常量表達式
code...
#endif
2.#ifdef DEBUG
code...
#endif
3.#ifndef DEBUG
code...
#endif