標籤:運算子 運算式 導致 處理過程 過程 double 標識 2.4 縮減
預先處理
前置處理器執行宏替換 條件編譯以及包含指定的檔案以#開頭的命令列(#前可以有空格)就是前置處理器處理的對象預先處理過程可以劃分為幾個連續的階段1.將三字元序列轉換為等價字元。如果作業系統需要,還要在源檔案的各行之間插入分行符號2.將指令行中位於分行符號前的反斜線\刪除,以把各指令行串連起來3.將程式分成用空白符分隔的記號,注釋將被替換為一個空白符。接著執行預先處理指令,並進行宏替換4.將字串常量和字串字面量中的逸出字元序列替換為等價字元,然後把相鄰的字串字面值串連起來5.收集必要的程式和資料,並將外部函數和對象的引用與其定義相串連,翻譯經過以上處理得到的結果,然後與其他程式和庫串連起來
12.1 三字元序列
C語言來源程式的字元集是7位ASCII碼的子集,但它是ISO 646-1983不變代碼集的超集為了將程式通過這種縮減的字元集表示出來,下列所示的所有三字元序列都要用相應的單個字元替換這種替換在進行所有其他處理之前進行??=
12.2行串連
通過將以反斜線\結束的指令行末尾的反斜線和其後的分行符號刪除掉,可以將若干指令行合并成一行這種處理要在分隔記號之前進行
12.3宏定義和擴充
類似於下列形式的控制指令#define 標識符 記號序列將使得前置處理器把該標識符後續出現的各個執行個體用給定的記號序列替換記號序列前後的空白符都將被丟棄掉第二次用#define指令定義同一標識符是錯誤的類似於下列形式的標識符#define 標識符(標識符表) 記號標記是一個帶有參數的宏定義,其中第一個標識符與圓括弧(之間沒有空格)同第一種形式一樣,記號序列前後的空白符都將被丟棄。如果要對宏進行重定義,則必須保證其參數個數 拼字及記號序列都與前面的定義相同#undef用於取消標識符的前置處理器定義將#undef應用於未知標識符並不會導致錯誤按照第二種形式定義宏時,標識符及其後用一對圓括弧括起來,由逗號分隔的記號序列就構成了一個宏調用宏調用的實際參數是用逗號分隔的記號序列用引號或嵌套的括弧括起來的逗號不能用於實際參數在處理的過程中,實際參數不進行宏擴充宏調用時,實際參數的數目必須與定義中形式參數的數目匹配
12.4檔案包含
#include <檔案名稱>把該行替換為檔案名稱指定的檔案的內容#include "檔案名稱"從源檔案的位置開始搜尋指定檔案,如果沒有找到指定的檔案,則按照第一種方式處理#include 記號序列#include 檔案可以嵌套
12.5條件編譯
if行:#if 常量運算式#ifdef 標識符#ifndef 標識符elif部分:elif行 文本 elif部分elif行 #elif 常量運算式else 部分else 行 文本else 行# else
12.6行控制
為了便於其他前置處理器產生C語言#line 常量 ‘ 檔案名稱"#line 常量將使編譯器認為:下一行原始碼的行號是以十進位常量的形式給出的並且,當前的輸入檔案是由該標識符命名的
12.7錯誤資訊產生
#error 記號序列使前置處理器列印包含該記號序列的診斷資訊
12.8pragma
#pragma 記號序列將使前置處理器執行一個與具體實現相關的操作 無法識別pragma將被忽略
12.9空指令
#形式的前置處理器將不執行任何操作
12.10預定義名字
某些標識符是預定義的,擴充後將產生特定的資訊它們同前置處理器運算式運算子defined一樣,不能取消定義或重新定義__LINE__ 包含當前源檔案函數__FILE__ 包含正在編譯的源檔案的字串__DATE__ 編譯日期 "Mmm dd yyyy"__TIME__ 編譯時間 "hh:mm:ss"__STDC__ 整型常量1
13文法
儲存類說明符:one ofauto register static extern typedef類型說明符:one ofvoid char short int long float double signed unsigned類型限定符:one ofconst volatile結構或聯合:one ofstruct union枚舉說明符:enum常量:整型常量字元常量浮點常量枚舉常量控制指令:#define 標識符 記號序列#define 標識符 (標識符表) 記號序列#undef 標識符#include <檔案名稱>#include "檔案名稱"#include 記號序列#line 常量 "檔案名稱"#line 常量#error 記號序列#pragma 記號序列
《C程式設計語言》筆記 (十四) 參考手冊6