1.預處理識別符號的使用:
#include#define __file__ //進行編譯的原始檔
#define __line__ //檔案當前的行號
#define __date__ //檔案被編譯的日期
#define __time__ //檔案被編譯的時間
int main()
執行結果:
這樣可以輸出當前編譯檔案的相關資訊,使用非常方便。
2.了解巨集和函式的區別
使用巨集的語法和使用函式的語法是完全一樣的,所以語言本身不能區分這兩者,一般情況下,我們將巨集的名字全部用大寫來區分。
巨集可以非常頻繁的用於執行簡單的計算,比如:
#define max(a,b) ((a)>(b)?(a):(b)) //求兩個數中較大的乙個
為什麼不用函式來完成,有兩個原因:
1)用於呼叫和函式返回的**很可能比實際執行這個小型計算工作的代價大,所以使用巨集比使用函式在程式的規模和速度更勝一籌。
2)但是更重要的是,函式的引數必須申明為一種特定的型別,所以函式只能在型別合適的表示式上使用。反之,巨集可以用於整形、長整形......以及其他任何可以使用》操作符
比較大小的型別。
巨集是和型別無關的。
和函式相比,使用巨集的不好處在於每次使用時,都要將巨集定義的**拷貝到程式中,除非巨集非常短,否則使用巨集可能會大幅度增加程式的長度。
還有一些任務函式無法實現,比如:
#include#define malloc(n,type) ((type*)malloc((n)*sizeof(type)))
int main()
這個程式經過預處理後得到:
int main()
這個巨集的第二個引數是一種型別,它無法作為函式引數進行傳遞。
3.巨集引數的***
當巨集引數在巨集定義中出現次超過一次時,如果這個引數具有***,那麼使用時就有可能導致不可預料的結果。比如
x++;
#include#define max(a,b) ((a)>(b)?(a):(b))
int main()
得到結果:
在這個程式中較小值計算了一次,但是較大值卻計算了兩次。
4.編譯鏈結的整個過程
1)預處理過程
(1)巨集替換
(2)標頭檔案展開
(3)取消注釋
(4)條件編譯
在編譯乙個程式時,如果我們可以選擇某條語句或某組語句進行翻譯或者被忽略,就會很方便,條件編譯就是用於實現這個目的的。
2)編譯過程(c程式**到彙編)
3)彙編過程(彙編到二進位制)
4)鏈結過程(將二進位制生成可執行程式的過程)
比如:
#include#define debug 1 //debug被定義則執行語句,值為1時執行,為0時不執行
#define realse 1
int main()
執行結果:
可以通過更改定義的值debug,realse來選擇執行哪條語句,可以起到很好的除錯作用。
指標的深度剖析
在c語言中,指標 pointer 是程式語言中的乙個物件,利用位址,它的值直接指向存在電腦儲存器中另乙個地方的值。由於通過位址能找到所需的變數單元,可以說,位址指向該變數單元。因此,將位址形象化的稱為 指標 意思是通過它能找到以它為位址的記憶體單元。指標變數和指標 將乙個變數的位址稱為變數的指標,存...
ifdef cplusplus深度剖析
時常在cpp的 之中看到這樣的 ifdef cplusplus extern c endif 這樣的 到底是什麼意思呢?首先,cplusplus是cpp中的自定義巨集,那麼定義了這個巨集的話表示這是一段cpp的 也就是說,上面的 的含義是 如果這是一段cpp的 那麼加入extern c 處理其中的 ...
深度剖析ostream
雖然c 學了大半個月了,自己學了解了很多關於c 的知識,大的概念懂了不少,但是還是想說想要徹底的弄懂c 絕非易事。當別人問到乙個很小的知識點些許你都要愣很久,事實告訴我們不能太好高騖遠。為什麼要寫ostream而不是istream,因為當我們自定義型別 student類 的時候,如果需要輸出 stu...