寫在前面的話:經過一段時間的學習我發現,有很多語法知識我并沒有足夠的理解,我記得有人曾和我說過,理解語法需要換個角度,如果你作為一個C語言創始人,你會怎么做?
舉個例子,傳參,將數組降價為指針,既節省了空間,又讓程序媛在編寫程序時方便了許多。所以有些時候換個角度,換種環境去理解。你會深刻的感受到那句話——驀然回首那人卻在燈火闌珊處。。。。
預處理
執行宏替換,條件編譯,包含指定頭文件,去掉注釋。所有以#開頭的命令行都是預處理要處理的對象
這些命令行的語法獨立于語言的其他部分,它們可以出現在任何地方其作用可延續到所在翻譯單元的末尾,與作用域無關
行邊界有實際意義:通過將以反斜杠/結束的指令行末尾的反斜杠/與其后面的換行符刪除。可以將若干指令行合并成一行。這種處理要在分割記號之前進行。
預處理記號:可以是任意語言記號,也可以是#include指令
文件包含指令#include控制指令形式:
1.#include<文件名>
該行將被替換為文件名指定的文件內容
文件名不可包含>或換行符
文件名非法字符 “、`、/*
2.#include"文件名"
先從源文件位置開始搜索文件,如找到按上面定義方式處理也就是會在對應的引用目錄中查找對應頭文件,意思就是,如果使用#Include "stdio.h",如果你項目目錄中沒有這個頭文件,它會定位到C:/Keil/c51/INC/stdio.h這個頭文件
如文件名包含字符 “、`、/*仍非法
可以使用字符>
3.#include 記號序列
同上述兩種方式不同,它將按照擴展文本的方式擴展記號序列進行解釋。記號序列必須被解釋為<...>或"...",兩種方式之一,再按照上述方式處理
#include文件可以嵌套
http://blog.csdn.net/zhu_liangwei/article/details/9745179
(這里有嵌套的具體解釋,還包括了條件編譯的解釋)
http://blog.csdn.net/gmpy_tiger/article/details/50903620
(這是我在學習上面文章講述內容中遇到的問題,關于Makefile gcc 的)
http://blog.csdn.net/gmpy_tiger/article/details/50903620
編譯 檢查語法
編譯時,編譯器需要的是語法的正確,函數與變量的聲明的正確。對于后者,通常是你需要告訴編譯器頭文件的所在位置(頭文件中應該只是聲明,而定義應該放在C/C++文件中),只要所有的語法正確,編譯器就可以編譯出中間目標文件。一般來說,每個源文件都應該對應于一個中間目標文件(O文件或是OBJ文件)。
鏈接
鏈接時,主要是鏈接函數和全局變量,所以,我們可以使用這些中間目標文件(O文件或是OBJ文件)來鏈接我們的應用程序。鏈接器并不管函數所在的源文件,只管函數的中間目標文件(Object File),在大多數時候,由于源文件太多,編譯生成的中間目標文件太多,而在鏈接時需要明顯地指出中間目標文件名,這對于編譯很不方便,所以,我們要給中間目標文件打個包,在Windows下這種包叫“庫文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。
可執行文件
總結一下,源文件首先會生成中間目標文件,再由中間目標文件生成執行文件。在編譯時,編譯器只檢測程序語法,和函數、變量是否被聲明。如果函數未被聲明,編譯器會給出一個警告,但可以生成Object File。而在鏈接程序時,鏈接器會在所有的Object File中找尋函數的實現,如果找不到,那到就會報鏈接錯誤碼(Linker Error),在VC下,這種錯誤一般是:Link 2001錯誤,意思說是說,鏈接器未能找到函數的實現。你需要指定函數的Object File.
新聞熱點
疑難解答