欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++中的extern聲明變量詳解

 更新時(shí)間:2015年03月17日 09:39:57   投稿:junjie  
這篇文章主要介紹了C++中的extern聲明變量詳解,本文講解了聲明和定義、extern聲明全局變量、extern聲明函數(shù)等內(nèi)容,需要的朋友可以參考下

extern聲明變量無(wú)外乎如下兩種:

1、聲明全局變量
2、聲明函數(shù)

今天我們只談extern,什么const、static之類(lèi)等等與之相關(guān)或不相關(guān)的一律忽略,下面就分別對(duì)以上兩種情況一一講解

聲明和定義
既然提到extern聲明變量,那我們就必須搞清楚聲明和定義的區(qū)別。

這里我們將普通數(shù)據(jù)變量和函數(shù)統(tǒng)稱(chēng)變量。從內(nèi)存分配角度來(lái)說(shuō),聲明和定義的區(qū)別在于聲明一個(gè)變量不會(huì)分配內(nèi)存,而定義一個(gè)變量會(huì)分配內(nèi)存。一個(gè)變量可以被聲明多次,但是只能被定義一次。

基于以上前提,我們可以把聲明和定義類(lèi)比為指針和內(nèi)存的關(guān)系。我們知道,指針其實(shí)就是指向內(nèi)存的一個(gè)符號(hào),變量的定義就好比一塊內(nèi)存區(qū)域,而聲明就好比它的指針,可以有多個(gè)指針指向同一個(gè)內(nèi)存區(qū)域,而一個(gè)指針只能指向一個(gè)內(nèi)存區(qū)域,這樣就很好理解為什么變量只能被定義一次,如果被定義多次,那就會(huì)分配多個(gè)內(nèi)存,這樣你通過(guò)變量的聲明到底去找哪塊內(nèi)存區(qū)域呢,這會(huì)是個(gè)問(wèn)題。

對(duì)于數(shù)據(jù)來(lái)說(shuō),聲明和定義往往是同時(shí)存在的,比如下面的一行語(yǔ)句

復(fù)制代碼 代碼如下:

int data; 

這樣既聲明了data同時(shí)也定義了data,怎樣做到只聲明而不定義呢,用extern就可以了
復(fù)制代碼 代碼如下:

extern int data;

對(duì)于函數(shù)來(lái)說(shuō),聲明和定義就很容易區(qū)分了,一般我們會(huì)將聲明放在頭文件而將定義放在源文件里
復(fù)制代碼 代碼如下:

void hello(); 

這是一個(gè)函數(shù)的聲明,而
復(fù)制代碼 代碼如下:

void hello() 

    printf("hello world!\n"); 
}  

這是一個(gè)函數(shù)的定義。當(dāng)然,函數(shù)的聲明和定義也可以同時(shí)發(fā)生,如果我們沒(méi)有頭文件而只有源文件,并且在源文件里并沒(méi)有void hello();這樣的語(yǔ)句,那么這個(gè)函數(shù)的聲明和定義就同時(shí)發(fā)生了,此時(shí)如果我們?cè)谠募锵胍{(diào)用函數(shù)hello(),你調(diào)用的代碼必須在函數(shù)定義之后。

其實(shí)上面的要點(diǎn)只在于一句話(huà):使用變量之前必須聲明,聲明可以有多次,而定義只能有一次。記住這句話(huà),后面的就都很容易理解了。

extern聲明全局變量

我們先來(lái)看如下例子,現(xiàn)有三個(gè)文件:test.h, test.cpp, main.cpp,其中main.cpp和test.cpp需要共享一個(gè)變量g_name,三個(gè)文件的內(nèi)容如下

復(fù)制代碼 代碼如下:

/* test.h */ 
#ifndef _TEST_H_ 
#define _TEST_H_ 
 
#include <string> 
 
std::string g_name; 
void hello(); 
 
#endif 
 
/* test.cpp */ 
#include <stdio.h> 
#include "test.h" 
 
void hello() 

    printf("hello %s!\n", g_name.c_str()); 

 
/* main.cpp */ 
#include "test.h" 
 
std::string g_name; 
 
int main() 

    g_name = "Handy"; 
    hello(); 
    return 0; 

三者關(guān)系為,test.cpp包含了test.h,main.cpp也包含了test.h,這里的包含其實(shí)就是include。我們執(zhí)行編譯命令

復(fù)制代碼 代碼如下:

g++ main.cpp test.cpp 

編譯報(bào)錯(cuò)redefinition of 'g_name',說(shuō)的是g_name被重定義了

我們看一下g_name出現(xiàn)的地方,一個(gè)是在test.h里,一個(gè)是在main.cpp里,兩條語(yǔ)句都是std::string g_name,前面我們已經(jīng)說(shuō)過(guò),這樣的方式既聲明也定義了變量,那g_name是如何被重定義的呢,首先我們需要理解include的含義,我們可以將include一個(gè)頭文件理解為在該行展開(kāi)頭文件里的所有代碼,由于main.cpp包含了test.h,我們?cè)谀且恍袑est.h的內(nèi)容展開(kāi),就會(huì)發(fā)現(xiàn)main.cpp里有兩句std::string g_name;所以在main.cpp里,g_name被定義了兩次。

由于我們可以將include頭文件理解為展開(kāi)代碼,所以編譯的時(shí)候其實(shí)不需要指定頭文件,只需要源文件就夠了。需要注意的是,重定義并不是指在同一個(gè)原文件里定義多次,而是指在整個(gè)代碼空間里,比如上面的例子是就是指在test.cpp和main.cpp里,其實(shí)上面的例子里g_name是被重定義了三次,其中test.cpp里一次,main.cpp里兩次。

那上面重定義的問(wèn)題怎么解決呢,很簡(jiǎn)答,將test.h里的std::string g_name;改為extern std::string g_name;就可以了,由于extern語(yǔ)句只聲明變量而不定義變量,因此test.cpp和main.cpp展開(kāi)頭文件后,也只是將g_name聲明了兩次,而真正的定義還是在main.cpp里

extern聲明函數(shù)

還是上面的例子,我們?cè)趺丛趍ain.cpp里不包含頭文件就可以調(diào)用hello函數(shù)呢,既然今天的主題是extern,不用提醒也知道,使用extern就可以了,代碼如下

復(fù)制代碼 代碼如下:

/* test.cpp */ 
#include <string> 
#include <stdio.h> 
 
// 聲明g_name 
extern std::string g_name;         
 
// 聲明和定義void hello() 
void hello()                       

    printf("hello %s!\n", g_name.c_str()); 

 
/* main.cpp */ 
#include <string> 
 
// 聲明和定義g_name 
std::string g_name;    
 
// 聲明void hello()            
extern void hello();              
 
int main() 

    g_name = "Handy" 
    hello(); 
    return 0; 

注意這里用到extern聲明變量和函數(shù)兩種場(chǎng)景,我分別在語(yǔ)句后面做了注釋。編譯命令如下

復(fù)制代碼 代碼如下:

g++ main.cpp test.cpp 

這里我們并沒(méi)有用到頭文件,但是依然可以在不同文件間共享變量和函數(shù),這一切都是extern的功勞!

總結(jié)

要了解extern主要搞清以下幾個(gè)概念:

1、聲明和定義的區(qū)別。全局代碼空間里,變量可以有多個(gè)聲明,但只能有一個(gè)定義
2、include頭文件等同于展開(kāi)頭文件里的代碼

了解了以上兩點(diǎn),再來(lái)分析extern的用法,是不是就會(huì)清晰很多了

相關(guān)文章

  • C語(yǔ)言?超詳細(xì)講解鏈接器

    C語(yǔ)言?超詳細(xì)講解鏈接器

    在C語(yǔ)言中,一個(gè)重要的思想就是分別編譯,即若干個(gè)源程序能夠在不一樣的時(shí)候單獨(dú)進(jìn)行編譯,而后在恰當(dāng)?shù)臅r(shí)候整合到一塊兒??墒擎溄悠魍ǔJ桥cC編譯器分離的,鏈接器如何作到把若干個(gè)C源程序合并成一個(gè)總體呢,我們一起來(lái)看看
    2022-03-03
  • 一文搞懂Codec2解碼組件

    一文搞懂Codec2解碼組件

    這篇文章主要介紹了Codec2解碼組件,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • C++如何去掉字符串首尾的空格

    C++如何去掉字符串首尾的空格

    這篇文章主要介紹了C++如何去掉字符串首尾的空格問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語(yǔ)言實(shí)現(xiàn)反彈球小游戲

    C語(yǔ)言實(shí)現(xiàn)反彈球小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)反彈球小游戲,利用函數(shù)寫(xiě)的C語(yǔ)言小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-02-02
  • C++ sort排序之降序、升序使用總結(jié)

    C++ sort排序之降序、升序使用總結(jié)

    這篇文章主要介紹了C++ sort 排序(降序、升序)使用總結(jié),需要的朋友可以參考下
    2020-11-11
  • 教你用Matlab制作黃金礦工小游戲

    教你用Matlab制作黃金礦工小游戲

    黃金礦工作為經(jīng)典的單機(jī)小游戲,一直深受大家的喜愛(ài)。本文將用Matlab制作這一款經(jīng)典的游戲,文中的實(shí)現(xiàn)步驟講解詳細(xì),感興趣的可以了解一下
    2022-03-03
  • C語(yǔ)言超詳細(xì)講解隊(duì)列的實(shí)現(xiàn)及代碼

    C語(yǔ)言超詳細(xì)講解隊(duì)列的實(shí)現(xiàn)及代碼

    隊(duì)列(Queue)與棧一樣,是一種線性存儲(chǔ)結(jié)構(gòu),它具有如下特點(diǎn):隊(duì)列中的數(shù)據(jù)元素遵循“先進(jìn)先出”(First?In?First?Out)的原則,簡(jiǎn)稱(chēng)FIFO結(jié)構(gòu)。在隊(duì)尾添加元素,在隊(duì)頭刪除元素
    2022-04-04
  • c++函數(shù)指針使用示例分享

    c++函數(shù)指針使用示例分享

    這篇文章主要介紹了c++函數(shù)指針使用示例,需要的朋友可以參考下
    2014-03-03
  • 基于排列與組合輸出多少中情況詳解

    基于排列與組合輸出多少中情況詳解

    本篇文章對(duì)排列與組合輸出多少中情況進(jìn)行了介紹。需要的朋友參考下
    2013-05-05
  • C++程序的執(zhí)行順序結(jié)構(gòu)以及關(guān)系和邏輯運(yùn)算符講解

    C++程序的執(zhí)行順序結(jié)構(gòu)以及關(guān)系和邏輯運(yùn)算符講解

    這篇文章主要介紹了C++程序的執(zhí)行順序結(jié)構(gòu)以及關(guān)系和邏輯運(yùn)算符講解,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論