巨集定義與預定義
上學的時候就沒搞清楚這兩個東東的關係,原本以為是多麼難得事情,今天仔細瞧瞧就那麼回事。(浮躁的大學哦.....)
巨集定義:
其作用就是“換其名曰”,給程式中的一段特殊的程式碼--函式,資料取了個簡單明瞭的名字。不過有一點這傢伙的作用範圍是全域性的。即使它是在某一個函式塊中定義的。這個其實也容易理解。因為巨集定義是預定義的一種,在我們的程式之前,由預編譯器(Cpp)提前編譯出來了,那個時候程式裡的結構是個啥樣子編譯器壓根就不知道。所以作用範圍是全域性的是“必須”的。在C#中巨集定義是不被支援的!!俺覺得這個決定是對的。因為這玩意兒本身就破壞類的封裝性,如果需要全域性靜態變數,完全可以定義一個靜態類的靜態成員。
class Test
{
public void test()
{
Console.WriteLine(parameters.para);
}
}
static class parameters
{
public static string para = "something";
}
巨集定義與靜態變數:
靜態變數與巨集定義其實沒啥關係,所謂的靜態,也只是說它儲存的位置實在“全域性變數的記憶體區”但是它使用起來還是有範圍限制的。
巨集定義與常量:
巨集定義與常量都有“換其名曰”的作用,但是巨集定義的作用範圍只能是全域性的,而常量是在編譯過程中由編譯器搞出來的,所以常量的作用域有全域性和區域性之分。如果在一個函式中定義了一個常量,那麼這個常量的作用範圍就僅限於這個函式。而如果在這個函式中定義了一個巨集定義,那麼這個巨集定義在函式外也是可以訪問定的。為嘛?因為人家是在編譯之前就被搞出來的。跟這個函式其實沒多大關係,所以偶感覺如果要定義一個巨集,乾脆直接定義在檔案頭部分。簡單明瞭。
預定義:
預定義算一種特殊的機制吧,就是有一些變數或函式需要在我們程式被編譯之前就被搞出來,那麼就需要在編譯器發揮作用之前啟動一個叫預編譯器的東西,它會搜尋程式裡邊帶"#" 的程式碼,然後把它們提前給編譯了。這之後再啟動編譯器進行編譯。預定義指令其實是為了配合這種機制而定義出來的旨在我們的程式中對需要與處理的程式碼段進行標識的一種命令。他的作用包括巨集定義,檔案包含,和條件編譯。
巨集定義我們已經嘮叨完了,檔案包含就是我們常見的#include,這裡頭還是要囉嗦一下氣候的規則#include<iostream.h>和#include<iostream>是由於標準的不一樣,由於有些大牛覺得".h"檔案作為標頭檔案表示不利於統一,所以就早早的把這個給去掉了。還有另外的原因就是<iosteam>和<iostream.h>裡邊的標準也變了,說白了就是不是一個檔案了,裡邊的東東發生了變化,用#include<iostream>會包含進去一個比較新版本的iostream(副檔名未知). <>和""的區別在於查詢的位置不一樣,<>從標準庫的標頭檔案中開始查詢,""從使用者自定義的標頭檔案庫中開始查詢。
餘下的預定義指令就掛在下邊,比較好理解。可以說預編譯機制是一個“無奈”的機制,預編譯指令最終的歸宿應該是被嵌入到程式碼中,與其他的程式碼一起被編譯器編譯。
最後---在許多年之後---將Cpp放逐到程式開發環境裡,與其它附加性語言工具放到一起,那裡才是她應該呆的地方。” 一個大牛說的,瞭解了就行。
#define 巨集定義
#undef 未定義巨集
#include 文字包含
#ifdef 如果巨集被定義就進行編譯
#ifndef 如果巨集未被定義就進行編譯
#endif 結束編譯塊的控制
#if 表示式非零就對程式碼進行編譯
#else 作為其他預處理的剩餘選項進行編譯
#elif 這是一種#else和#if的組合選項
#line 改變當前的行數和檔名稱
#error 輸出一個錯誤資訊
#pragma 為編譯程式提供非常規的控制流資訊