最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++中的名字空間與作用域示例詳解

 更新時(shí)間:2017年09月13日 10:59:27   作者:青兒哥哥  
這篇文章主要給大家介紹了關(guān)于C/C++中名字空間與作用域的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用c/c++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧。

前言

本文主要給大家介紹了關(guān)于C/C++中名字空間與作用域的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話(huà)不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。

C語(yǔ)言中有名字空間這個(gè)概念嗎?

提到名字空間(或者可能更普遍的叫法,命名空間),很可能先想到的是C++,甚至是C#。C中沒(méi)有名字空間吧?一開(kāi)始我也是這樣認(rèn)為的,直到我看了C primer plus這本書(shū),才直到C語(yǔ)言中其實(shí)也有名字空間的概念!而為什么我們更熟悉C++中的名字空間呢?可能是因?yàn)槲覀円恍〤++程序,不過(guò)知不知道為什么,總是要加上一句using namespace std;吧。其實(shí)C語(yǔ)言中也是有名字空間的概念的,只不過(guò)C語(yǔ)言中不能自定義名字空間,而C++中,我們可以定義自己的名字空間。

C語(yǔ)言中的名字空間和作用域

在網(wǎng)上看過(guò)很多資料,很多人都認(rèn)為名字空間是作用域的一個(gè)補(bǔ)充,認(rèn)為名字空間是為了區(qū)分同一作用域下相同的標(biāo)識(shí)符,解釋的也有一定道理。但是我在C primer plus中理解的是作用域是對(duì)名字空間的一個(gè)補(bǔ)充。我是這樣理解的:名字空間之間是相互獨(dú)立的,但是作用域之間卻有包含的關(guān)系,比如說(shuō)一個(gè)全局變量和一個(gè)函數(shù)內(nèi)部的局部變量,全局變量的作用域是文件作用域,而局部變量的作用域是塊作用域,但是在函數(shù)內(nèi)部全局變量就消失了嗎?沒(méi)有呀,我們依然可以訪(fǎng)問(wèn)全局變量,只不過(guò)當(dāng)局部變量和全局變量同名時(shí),全局變量被隱藏了而已??赡苡悬c(diǎn)糊涂,沒(méi)關(guān)系,往下看。

C語(yǔ)言中有4中名字空間

C語(yǔ)言中的四種名字空間分別為:

1、 所有的標(biāo)簽(label)都屬于同一個(gè)命名空間。

2、 struct、union和enum的名稱(chēng),在C99中稱(chēng)之為tag,所有的tag屬于同一個(gè)命名空間。

也就是說(shuō),如果你已經(jīng)聲明struct  A { int a }; 就不能再聲明 union A { int a };

說(shuō)明:之所以讓所有的tag組成一個(gè)命名空間,由于tag前面總是帶struct、union和enum關(guān)鍵字,所以編譯器可以將它們與其他的標(biāo)識(shí)符區(qū)分開(kāi)。

3、 struct和union的成員位于它們各自struct或union命名空間下,相互獨(dú)立互不影響,并且可以形成遞歸的命名空間(如struct中在定義struct)。

例如:如果你已經(jīng)聲明 struct A { int a };其成員的名稱(chēng)為a,你仍然可以聲明 struct B { int a}; 或者 union B { int a };

說(shuō)明:之所以讓struct和union成員各自成為一個(gè)命名空間,是因?yàn)樗鼈兊某蓡T訪(fǎng)問(wèn)時(shí),需要通過(guò)"."或"->"運(yùn)算符,而不會(huì)單獨(dú)使用,所以編譯器可以將它們與其他的標(biāo)識(shí)符區(qū)分開(kāi)。由于枚舉類(lèi)型enum的成員可以單獨(dú)使用,所以枚舉類(lèi)型的成員不在這一名稱(chēng)空間類(lèi)。

4、 其他所有的標(biāo)識(shí)符,屬于同一個(gè)命名空間。包括變量名、函數(shù)、函數(shù)參數(shù),宏定義、typedef的類(lèi)型名、enum的成員等等。

C語(yǔ)言中有4種作用域

C語(yǔ)言中四種作用域?yàn)椋?/p>

1、塊作用域

塊作用域作用域整個(gè)大括號(hào)中,比如一個(gè)函數(shù)中的局部變量就具有塊作用域。還要注意,函數(shù)頭中的形式參數(shù)也是塊作用域,它的作用范圍也是整個(gè)函數(shù)體

2、文件作用域

文件作用域也叫全局作用域,作用范圍是整個(gè)文件。全局作用域有鏈接屬性一說(shuō),分為內(nèi)部鏈接屬性(靜態(tài)鏈接屬性)和外部鏈接屬性。當(dāng)全局變量被static修飾的時(shí)候,有內(nèi)部鏈接屬性,也就是作用域?yàn)楸?c文件,在其他.c文件中是不可見(jiàn)的。而當(dāng)全局變量被extern修飾的時(shí)候(也是默認(rèn)的情況,如果不寫(xiě),就默認(rèn)extern),有外部鏈接屬性,也就是不僅作用域本.c文件,也作用域其他.c文件。之所以叫鏈接屬性,是因?yàn)镃語(yǔ)言的編譯單元為一個(gè).c文件,也就是說(shuō),如果在不同的.c文件中含有同名的全局變量,在編譯的時(shí)候是不會(huì)發(fā)現(xiàn)錯(cuò)誤的,因?yàn)椴煌?c文件時(shí)分別編譯的,編譯時(shí)期是相互獨(dú)立的。但是在鏈接階段就會(huì)報(bào)錯(cuò)。

3、函數(shù)作用域

注意和塊作用域相互區(qū)分,函數(shù)體中的局部變量具有塊作用域,而不是函數(shù)作用域。所謂函數(shù)作用有,只針對(duì)“標(biāo)號(hào)”。什么意思呢?我們知道C語(yǔ)言有個(gè)goto語(yǔ)句(當(dāng)然由于goto語(yǔ)句使程序的邏輯混亂,所以C++中摒棄了goto語(yǔ)句),那么我們要goto到什么地方呢?這個(gè)地方是用一個(gè)叫“標(biāo)號(hào)”的東西表示的。比如我們用goto語(yǔ)句實(shí)現(xiàn)一個(gè)循環(huán)。

int i,sum=0;

i=1;

loop: if(i<=100)

{

  sum=sum+i;

  i++;

  goto loop;

}

其中l(wèi)oop就是標(biāo)號(hào),他的作用域叫函數(shù)作用域,在函數(shù)內(nèi)部有效。

4、函數(shù)原型作用域

函數(shù)原型作用域就是在函數(shù)原型聲明時(shí),形參的作用域。

比如 void fun(int a,int b);

其中a和b的作用域就是函數(shù)原型作用域,作用域小括號(hào)內(nèi)部。注意和函數(shù)定義時(shí),形參的作用域相區(qū)別,定義時(shí),函數(shù)形參的作用域是塊作用域,在函數(shù)體內(nèi)有效。

同一名字空間中的同一個(gè)作用域中,名字(標(biāo)識(shí)符)只能唯一

直接看例子吧,來(lái)的比較直接一些。

#include <stdio.h>

int fun = 10;

void fun()

{

  printf("hahaha\n");

}

 

int main()

{

  return 0;

}

結(jié)果:編譯時(shí)出錯(cuò)!

 

原因就是 全局變量fun和函數(shù)fun有著相同的名字空間,都是位于第4種名字空間中,而且兩者的作用域都是文件作用域,同一名字空間和同一作用域中是不能夠有相同的標(biāo)識(shí)符的。

再來(lái)看一個(gè)例子:

#include <stdio.h>

struct fun{

  int a;

  int b;

};

void fun()

{

  printf("hahaha\n");

}

 

int main()

{

  return 0;

}

結(jié)果:通過(guò)編譯,沒(méi)有問(wèn)題。

這是因?yàn)?,雖然struct fun和函數(shù)fun有著相同的作用域,都是文件作用域,但是有著不同的名字空間,struct fun屬于第二種名字空間,而函數(shù)fun屬于第四種名字空間。

在看一個(gè)例子:

#include <stdio.h>

struct fun{

   int a;

   int b;

};

void fun()

{

   printf("hahaha\n");

}

 

int main()

{

   struct fun fun;

   fun.a = 10;

   fun.b = 20;

   return 0;

}

結(jié)果:編譯通過(guò)

我們來(lái)看 struct fun fun;這個(gè)語(yǔ)句,兩個(gè)fun并不沖突,因?yàn)樗麄冇兄煌拿挚臻g。第一個(gè)fun位于第二種名字空間中,而第二個(gè)fun位于第三種名字空間中,所以不沖突。

再來(lái)看一個(gè)例子:

#include <stdio.h>

struct fun{

   int a;

   int b;

};

enum fun{

   A,

   B,

   C

};

 

int main()

{

   return 0;

}

結(jié)果:編譯錯(cuò)誤

 

原因:struct funenum fun中的fun有著相同的名字空間,都是位于第二種名字空間中,而且他們的作用域都是文件作用域,所以一樣啦。

再來(lái)看一個(gè)例子:

#include <stdio.h>

int a = 10;

int b = 20;

 

int main()

{

   int b = 30;

   a = 50;

   printf("a = %d,b = %d\n",a,b);

   return 0;

}

結(jié)果:通過(guò)編譯,沒(méi)有問(wèn)題

原因,變量loop和標(biāo)號(hào)loop位于不同的名字空間,變量loop位于第四種名字空間,而標(biāo)號(hào)loop位于第一種名字空間。

最后再看一個(gè)例子:

#include <stdio.h>

int a = 10;

int b = 20;

 

int main()

{

   int b = 30;

   a = 50;

   printf("a = %d,b = %d\n",a,b);

   return 0;

}

結(jié)果,編譯通過(guò):且輸出為:

 

原因 雖然全局變量和局部變量位于同一個(gè)名字空間中,都是位于第4中名字空間中,但是全局變量b的作用域?yàn)槲募饔糜颍植孔兞縝的作用域?yàn)閴K作用域,作用域小的b會(huì)將作用域大的b隱藏掉。

其實(shí)這就是我認(rèn)為,作用域是名字空間的一個(gè)補(bǔ)充,的原因。

兩個(gè)b有著同樣的名字空間,但是有著大小不同的作用域,實(shí)際上文件作用域的作用范圍是包含塊作用域的作用范圍的,這也是為什么在函數(shù)內(nèi)部依然可以訪(fǎng)問(wèn)全局變量a的原因。作用域?qū)嶋H上是包含的關(guān)系,小的作用域會(huì)將大的作用域隱藏掉。但是名字空間之間卻是相互獨(dú)立的,這一點(diǎn)在C++中,自定義名字空間時(shí),會(huì)體會(huì)的更深刻。

再次表明一下我的觀(guān)點(diǎn),我認(rèn)為,作用域是對(duì)名字空間的一個(gè)補(bǔ)充,當(dāng)在同一個(gè)名字空間中,用作用域來(lái)描述名字(也就是標(biāo)識(shí)符)的可見(jiàn)性,小的作用域會(huì)隱藏大的作用域。

下面說(shuō)說(shuō)C++中的名字空間。

首先,C++中繼承了C語(yǔ)言中的名字空間,也就是那四類(lèi)名字空間在C++中依然適用。需要說(shuō)明的是,類(lèi)的名字,位于第二種名字空間中,類(lèi)中的成員的名字位于第三種名字空間中,這一點(diǎn)和struct、enum等類(lèi)似。

C++中允許我們自定義名字空間,自定義的方法就是適用namespace關(guān)鍵字。

先考慮這樣一個(gè)問(wèn)題:

一個(gè)工程中有多個(gè).c文件,其中一個(gè).c文件讓柯南完成,另外一個(gè).c文件讓小蘭完成。這兩個(gè)人心有靈犀,都定義了一個(gè)叫conan的全局變量,這個(gè)時(shí)候當(dāng)工程鏈接的時(shí)候就會(huì)報(bào)錯(cuò)。原因是兩個(gè)conan有同樣的名字空間,都是位于第4種名字空間中,也有著同樣的作用域,都是文件作用域,于是這兩個(gè)conan就沖突了。

怎么解決呢?

前面提到過(guò),只有同一個(gè)名字空間中同一作用域下,相同的名字才會(huì)沖突。所以要解決沖突無(wú)非就是修改名字空間或者作用域。首先說(shuō)修改作用域,前面提到過(guò),文件作用域的標(biāo)識(shí)符有一個(gè)鏈接屬性,static修飾的,的作用域僅僅限于本.c文件,而extern(或者默認(rèn)情況下)作用域是所有.c文件,所以我們可以個(gè)其中一個(gè)conan加上static修飾,這樣就改變了作用域,就不會(huì)沖突了,但是問(wèn)題是,我們既然定義成全局變量,通常情況下,我們都希望它有外部鏈接屬性。我們之所以定義成全局變量,很可能就是為了讓其他.c文件使用。所以static雖然解決了沖突,但是沒(méi)有達(dá)到我們的目的。那么我們只能夠用另一種方法解決沖突了,就是修改名字空間,這在C語(yǔ)言中是不可行的,因?yàn)镃語(yǔ)言中就那4中名字空間。但是在C++中是可行的,因?yàn)镃++可以自定義名字空間。

于是柯南將他的int conan;寫(xiě)成了:

namespace nan

{

  int conan;

}

小蘭將他的int conan;寫(xiě)成了:

namespace lan

{

  int conan;

}

這樣柯南的conan就在名字空間nan中了,而小蘭conan就在名字空間lan中了,就不沖突了。

但是需要注意,在其他文件中引用時(shí),需要帶上名字空間名比如,lan.conan;

至于namespace的詳細(xì)用法,以及using namespace的使用,就不寫(xiě)了,大家看書(shū)就好。

最后提一下C語(yǔ)言中怎樣解決命名沖突。

C語(yǔ)言中怎樣解決命名沖突呢?C語(yǔ)言并不支持自定義名字空間,所以解決命名沖突貌似只能是:1、 如果可能的話(huà)用static修飾(有些情況是不能能用static修飾的,比如提供給外部使用的函數(shù))2、在命名上下功夫,比如使用前綴,比如libnids庫(kù)中的所有函數(shù)都是nids_開(kāi)頭的。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • C語(yǔ)言枚舉的使用以及作用

    C語(yǔ)言枚舉的使用以及作用

    這篇文章主要介紹了C語(yǔ)言枚舉的使用以及使用,閱讀下面內(nèi)容我們將掌握枚舉的相關(guān)概念、掌握枚舉的幾種用法、掌握枚舉在實(shí)際產(chǎn)品中的用法,需要的朋友可以參考一下
    2022-03-03
  • win10+VS2017+Cuda10.0環(huán)境配置詳解

    win10+VS2017+Cuda10.0環(huán)境配置詳解

    這篇文章主要介紹了win10+VS2017+Cuda10.0環(huán)境配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • C語(yǔ)言轉(zhuǎn)義字符詳解

    C語(yǔ)言轉(zhuǎn)義字符詳解

    這篇文章主要介紹了C語(yǔ)言轉(zhuǎn)義字符詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了C語(yǔ)言轉(zhuǎn)義字符該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++編程模板匹配超詳細(xì)的識(shí)別手寫(xiě)數(shù)字實(shí)現(xiàn)示例

    C++編程模板匹配超詳細(xì)的識(shí)別手寫(xiě)數(shù)字實(shí)現(xiàn)示例

    大家好!本篇文章是關(guān)于手寫(xiě)數(shù)字識(shí)別的,接下來(lái)我將在這里記錄我的手寫(xiě)數(shù)字識(shí)別的從零到有,我在這里把我自己的寫(xiě)代碼過(guò)程發(fā)出來(lái),希望能幫到和我一樣努力求知的人
    2021-10-10
  • C++ Boost Flyweight庫(kù)使用介紹

    C++ Boost Flyweight庫(kù)使用介紹

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)
    2022-12-12
  • C++中的throw關(guān)鍵字詳解

    C++中的throw關(guān)鍵字詳解

    throw關(guān)鍵字是在C語(yǔ)言中用來(lái)拋出異常的關(guān)鍵字,它通常與try和catch一起使用,用于在程序中發(fā)生錯(cuò)誤時(shí)進(jìn)行異常處理,當(dāng)遇到無(wú)法處理的錯(cuò)誤情況時(shí),我們可以使用throw關(guān)鍵字主動(dòng)拋出異常,所以本文給大家詳細(xì)的介紹一下C++中的throw關(guān)鍵字,需要的朋友可以參考下
    2023-09-09
  • c++隱式類(lèi)型轉(zhuǎn)換示例分享

    c++隱式類(lèi)型轉(zhuǎn)換示例分享

    這篇文章主要介紹了c++隱式類(lèi)型轉(zhuǎn)換的二個(gè)示例,需要的朋友可以參考下
    2014-03-03
  • 使用C++ MFC編寫(xiě)一個(gè)簡(jiǎn)單的五子棋游戲程序

    使用C++ MFC編寫(xiě)一個(gè)簡(jiǎn)單的五子棋游戲程序

    這篇文章主要介紹了使用C++ MFC編寫(xiě)一個(gè)簡(jiǎn)單的五子棋游戲程序,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • C++報(bào)錯(cuò):Segmentation Fault的解決方案

    C++報(bào)錯(cuò):Segmentation Fault的解決方案

    段錯(cuò)誤(Segmentation Fault)是 C++ 編程中常見(jiàn)且令人頭疼的錯(cuò)誤之一,段錯(cuò)誤通常發(fā)生在程序試圖訪(fǎng)問(wèn)未被允許的內(nèi)存區(qū)域時(shí),導(dǎo)致程序崩潰,本文將深入探討段錯(cuò)誤的產(chǎn)生原因、檢測(cè)方法及其預(yù)防和解決方案,需要的朋友可以參考下
    2024-07-07
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單航班管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12

最新評(píng)論

灵川县| 大竹县| 安丘市| 信宜市| 民乐县| 成都市| 广平县| 湖南省| 宁陕县| 阿拉善盟| 泽库县| 孟州市| 马关县| 金平| 广灵县| 南溪县| 青海省| 无锡市| 海门市| 内黄县| 东安县| 唐河县| 建瓯市| 石首市| 崇义县| 福鼎市| 诏安县| 财经| 凤庆县| 民权县| 张家口市| 蛟河市| 南京市| 翁牛特旗| 高雄市| 鹤山市| 丹阳市| 麻阳| 潞西市| 嘉善县| 浑源县|