c 之命名空間

2021-08-18 18:14:35 字數 3936 閱讀 2977

c語言中所有變數都有自己的作用域,宣告變數的型別不同,其作用域也不同。c語言中的變數,按照作用域的範圍可分為兩種, 即區域性變數和全域性變數,所對應的作用域為區域性作用域和全域性作用域。

簡單來說:

區域性作用域是指:在函式內作定義說明的。其作用域僅限於函式內, 離開該函式後再使用這種變數是非法的。

全域性作用域:也稱為外部變數,它是在函式外部定義的變數,可以在程式的任何地方訪問。 它不屬於哪乙個函式,它屬於乙個源程式檔案。其作用域是整個源程式。

在c++中,變數,函式和類都是大量存在的,如果這些變數,函式和類都是存在於全域性命名空間內,會導致很多衝突,這時我們就引入了命名空間來解決這個問題。

使用命名空間的目的就是對識別符號名稱進行本地化,以避免命名衝突或名字汙染,更好地控制識別符號的作用域。

作用域與命名空間:

宣告域(declaration region) —— 宣告識別符號的區域。

如:

在函式外面宣告的全域性變數,它的宣告域為宣告所在的檔案。

在函式內宣告的區域性變數,它的宣告域為宣告所在的**塊。

潛在作用域(potential scope)—— 從宣告點開始,到宣告域的末尾的區域。

因為c++採用的是先宣告後使用的原則,所以在宣告點之前的宣告域中,識別符號是不能用的。 

即,識別符號的潛在作用域,一般會小於其宣告域。

作用域(scope)—— 識別符號對程式可見的範圍。

識別符號在其潛在作用域內,並非在任何地方都是可見的。 

例如,區域性變數可以遮蔽全域性變數、巢狀層次中的內層變數可以遮蔽外層變數,從而被遮蔽的全域性或外層變數在其倍遮蔽的區域內是不可見的。

所以,乙個識別符號的作用域可能小於其潛在作用域。

2.命名空間:

命名空間(namespace)是一種描述邏輯分組的機制,可以將按某些標準在邏輯上屬於同乙個集團的宣告放在同乙個命名空間中。

原來c++識別符號的作用域分成**:**塊(,如復合語句和函式體)、類和全域性。現在,在其中的類和全域性之間,標準c++又新增了命名空間這乙個作用域級別。

命名空間可以是全域性的,也可以位於另乙個命名空間之中,但是不能位於類和**塊中。所以,在命名空間中宣告的名稱(識別符號),預設具有外部鏈結特性(除非它引用了常量)。

在所有命名空間之外,還存在乙個全域性命名空間,它對應於檔案級的宣告域。因此,在命名空間機制中,原來的全域性變數,現在被認為位於全域性命名空間中。

標準c++庫(不包括標準c庫)中所包含的所有內容(包括常量、變數、結構、類和函式等)都被定義在命名空間std(standard標準)中了。

命名空間的定義:

定義命名空間就相當於定義了乙個新的作用域,在這個命名空間結構中有函式或者(全域性)變數。

命名空間的定義有兩種形式:有名字的和無名字的。

有名的命名空間:

格式: 

namespace 命名空間名

例如:

namespace

n1

}

無名的命名空間:

格式: 

namespace

例如:

namespace

//沒有名字的命名空間-相當於當前檔案中的全域性變數,他的成員只能在當前檔案中使用,訪問時不用加命名空間名稱,對其他檔案不可見

說明:

命名空間的成員,是在命名空間定義中的花括號內宣告了的名稱。

可以在命名空間的定義內,定義命名空間的成員(內部定義)。

也可以只在命名空間的定義內宣告成員,而在命名空間的定義之外,定義命名空間的成員(外部定義)。

命名空間成員的外部定義的格式為:

命名空間名::成員名 ……
命名空間的特徵:

(1)命名空間可以巢狀

namespace

n2 namespace

n3

}}

(2)相同名字命名空間可以同時存在(前提是這兩個空間中沒有相同的變數或函式,否則會提示 「ambiguous symbol」的錯誤資訊)-系統會把多個相同命名空間內容整合在一起

namespacen1}

namespace

n1

命名空間的使用:

作用域解析運算子(::)

對命名空間中成員的引用,需要使用命名空間的作用域解析運算子'::'。
using指令(using namespace)

為了省去每次呼叫inner成員和標準庫的函式和物件時,都要新增outer::inner::和sta::的麻煩,可以使用標準c++的using編譯指令來簡化對命名空間中的名稱的使用。格式為:

using namespace 命名空間名[::命名空間名……];

在這條語句之後,就可以直接使用該命名空間中的識別符號,而不必寫前面的命名空間定位部分。因為using指令,使所指定的整個命名空間中的所有成員都直接可用。

using宣告(using)

除了可以使用using編譯指令(組合關鍵字using namespace)外,還可以使用using宣告來簡化對命名空間中的名稱的使用。格式為:

using 命名空間名::[命名空間名::……]成員名;

注意,關鍵字using後面並沒有跟關鍵字namespace,而且最後必須為命名空間的成員名(而在using編譯指令的最後,必須為命名空間名)。

與using指令不同的是,using宣告只是把命名空間的特定成員的名稱,新增該宣告所在的區域中,使得該成員可以不需要採用,(多級)命名空間的作用域解析運算子來定位,而直接被使用。

但是該命名空間的其他成員,仍然需要作用域解析運算子來定位。

2.使用命名空間

(1)直接載入命名空間

int main()

(2)使用using宣告—適用於使用命名空間內部少量內容

using n1::functest();

int main()

(3)使用using指令將命名空間所有內容匯入

using

namespace n1;

int main()

命名空間的名稱:

命名空間的別名:

標準c++引入命名空間,主要是為了避免成員的名稱衝突。若果使用者都給自己的命名空間取簡短的名稱,那麼這些命名空間本身,也可能發生名稱衝突。

如果為了避免衝突,而為命名空間取很長的名稱,則使用起來就會不方便。這是乙個典型的兩難問題。

標準c++為此提供了一種解決方案——命名空間別名,格式為:

namespace 別名 = 命名空間名;
另外,沒有名字的命名空間與static修飾哪一種方式比較好?

當我們在使用static關鍵字時會有一些限制,如不適用於是型別定義。 而匿名的名字空間則沒有這些問題。另一方面,static在不少地方被用到,而且含義各不相同,所以c++標準傾向於使用匿名名字空間。

詳見鏈結

static vs unnamed namespace

C 之命名空間

c中是沒有命名空間這個概念的,是c 中新引入的乙個東西,為了處理同名的衝突。其實命名空間就是封裝的乙個概念。把一些變數 函式 類給封裝起來。和類的封裝概念很像,但是比類的封裝要大。一 1.自定義定義命名空間 格式 namespacename namespace my 此 的目的就是想往命名空間std...

C 之命名空間

一 命名空間的定義與簡介 命名空間是ansi c 引入的可以由使用者命名的作用域,用來處理程式中常見的命名衝突。例如有兩個標頭檔案中都定義了student類,那麼在主程式中都包含這兩個標頭檔案時,使用student類便會編譯出錯。或者在程式中引入不同的庫時有相同的實體名,則在編譯時就會出現名字衝突。...

C 之命名空間

命名空間是隨著標準c 而引入的,它相當於乙個更加靈活的檔案域 全域性域 可以用花括號將檔案的一部分括起來,並以關鍵字namespace開頭,給它起乙個名字,這段區域即為命名空間域。命名空間可巢狀使用。namespace name1 namespace name2 name1 a 3 name2 a ...