1.編譯過程的簡介:
預編譯:
a.處理所有的注釋,以空格代替。
b.將所以#define刪除,並展開所有的巨集定義,字串替換。
c.處理條件編譯指令#if,#ifdef,#elif,#else,#endif
d.處理#include,並展開被包含的檔案,把頭檔案中的宣告,全部拷貝到檔案中。
e.保留編譯器需要使用的#pragma指令、
怎麼樣觀察這些變化呢?最好的方法就是在gcc中,輸入預處理指令,可以看看不同檔案經過預處理後變成什麼樣了,預處理指令:gcc -e file.c -o file.i 注意:-c -e一起使用是預編譯的時候保留注釋。
編譯:a.對預處理檔案進行一系列詞法分析,語法分析和語義分析
詞法分析:主要分析關鍵字,標示符,立即數等是否合法
語法分析:主要分析表示式是否遵循語法規則
語義分析:在語法分析的基礎上進一步分析表示式是否合法
b.分析結束後進行**優化生成相應的彙編**檔案編譯指令:gcc -s file.c -o file.s
彙編:彙編器將彙編**轉變為機器可以執行的指令,每個彙編語句幾乎都對應一條機器指令,其實機器指令就是機器碼,就是2進製碼。彙編指令:gcc -c file.c -o file.o 注意:-c是編譯彙編不連線。
再把產生的.o檔案,進行鏈結就可以生成可執行檔案。連線指令:gcc file.o file1.o -o file這句指令是鏈結file.o和file1.o兩個編譯並彙編的檔案,並生成可執行檔案file。
一般要想通過一條指令生成可執行檔案的指令是: gcc file.c -ofile
2.c語言中的預處理指令:#define、#undef(撤銷已定義過的巨集名)、#include、#if、#else、#elif、#endif、#ifdef、#ifndef、#line、#error、#pragma。還有一些ansi標準c定義的巨集:__line__、__file__、__data__、__time__、__stdc__。這樣使用printf("%s\n",__time__); printf(__date__);
乙個#undef的例子:
#include #include #include #define x 2
#define y x*2
#undef x
#define x 3
int main()
這個輸出的是6,說明了#undef的作用
3.巨集定義字串的時候:應該是 #define hello "hello world" 記住是雙引號。還有就是一切巨集都是不能有分號的,這個一定要切忌!!!
4.巨集與函式的比較:
a.巨集表示式在預編譯期被處理,編譯器不知道有巨集表示式存在
b.巨集表示式沒有任何的"呼叫"開銷
c.巨集表示式中不能出現遞迴定義
5.為什麼不在標頭檔案中定義全域性變數:
如果乙個全域性變數,想要在兩個檔案中,同時使用,那這兩個檔案中都應該#include這個標頭檔案,這樣的話就會出現重複定義的問題。其實是重名的問題,因為#include是分別在兩個檔案中展開的,試想一下,如果在兩個檔案中的開始部分,都寫上int a = 10; 是不是也會報錯。可能你會說那個#ifndef不是防止重複定義嗎?是的 ,那是防止在同乙個檔案中,同時出現兩次這個標頭檔案。現在是兩個檔案中,所以都要展開的。全域性變數就重名了!!!所以 對於全域性變數,最好是定義在.c檔案中,不要定義在標頭檔案中。
6.#pargma pack 設定字元對齊,看後面一節專門寫字元對齊問題的!!!
7.#運算子**換成字串):
假如你希望在字串中包含巨集引數,那我們就用#號,它把語言符號轉換成字串。
#define sqr(x) printf("the "#x"lait %d\n",((x)*(x)));
sqr(8)
輸出結果是:the 8 lait 64這個#號必須使用在帶參巨集中
有個小例子:
#include #include #include /*在字串中 加入巨集參用的*/
#define scan(n,string) scanf("%"#n"s",string); //n是擷取的個數 string是儲存的字串
int main()
8.##運算子(粘合劑)
一般用於貼上兩個東西,一般是用作在給變數或函式命名的時候使用。如#define xname(n) x##n
xname(8)為8n這個##號可以使用在帶參巨集或無參巨集中
下面是乙個##運算子的小例子,**如下:
#include #include #include #define bl1 bb##ll##1
#define bl(n) bbll##n
int main()
注意:#號和##號都必須只能在巨集定義中使用,不能使用在其他地方
9.其實預編譯這塊還有一些,不常用到的預編譯指令,也是盲點,但是不難理解,用到的時候查查就好。比如說#line、#error、#warning等。 C語言深度解剖讀書筆記 3 預編譯處理
1.編譯過程的簡介 預編譯 a.處理所有的注釋,以空格代替。b.將所以 define刪除,並展開所有的巨集定義,字串替換。c.處理條件編譯指令 if,ifdef,elif,else,endif d.處理 include,並展開被包含的檔案,把頭檔案中的宣告,全部拷貝到檔案中。e.保留編譯器需要使用的...
C語言深度解剖讀書筆記3
int p null 和 p null 的區別int p null 可以通過偵錯程式檢視p的值為 0x00000000 這句 的意思是 定義乙個指標變數p,其指向的記憶體裡面儲存的是 int 型別的資料 在定義變數p的同時把p的值設定為 0x00000000,而不是把 p 的值設定為0x000000...
讀書筆記《c語言深度解剖》 4
10.struct關鍵字 這裡struct關鍵字講解得比較少,主要有3點 1 空結構體的大小為1 在gcc下我的輸出是0 2 柔性陣列 在c99中,允許結構最後乙個元素是乙個大小未確定的陣列,這個陣列叫做柔性陣列。但是柔性陣列前面必須至少有乙個其他成員。用sizeof返回結構體大小的時候,並不包含柔...