C語言 全域性變數的定義與宣告

2021-09-27 12:03:34 字數 3560 閱讀 4596

**:

c語言中全域性變數的定義與宣告困擾著許多c語言初學者。本文講述了全域性變數定義與宣告的用法,而且本為也將闡述這種用法的內在原理。我們先從兩個錯誤例子引入,以下兩個例程都在vc6.0平台上測試。

兩種錯誤例程

1.unresolved external symbol

例子包含兩個c檔案(test.c)和(first.c)和乙個標頭檔案(test.h)。下邊具體展示下它們的**。

test.h內容

#ifndef _test_h

#define _test_h

extern int count;   

#endif

test.c內容

#include #include "test.h"

extern void fis_cal(void);

void main(void)

first.c內容

#include #include "test.h"

void fis_cal(void)

錯誤分析:test.h標頭檔案中宣告了全域性變數count,但是在兩個c檔案中都沒有對count進行定義,所以才會出現unresolved external symbol。

一種解決方法:隨便在兩個c檔案中加入一句「int count;」就ok了。例如我們加到test.c中,**如下。 

#include #include "test.h"

extern void fis_cal(void);

int count;

void main(void)

說明:加入的「int count;」就是對count的定義,預設的將其初始化為0。

結論:這種錯誤原因是「只宣告未定義」。

2.multiply defined symbols found

還是如此,三個檔案。但是,兩個c檔案與例程一中的檔案一樣,改動的只是標頭檔案。

test.h內容

#ifndef _test_h

#define _test_h

int count; 

#endif

錯誤分析:test.h標頭檔案中定義了全域性變數count,但是在兩個c檔案都通過「#include "test.h"」這句話對「int count;」進行了引用,所以造成了重複定義的錯誤。

一種解決方法:新增乙個「first.h」的標頭檔案,並且更改first.c的內容,具體更改如下。

first.h內容

#ifndef _first_h

#define _first_h

extern int count;

#endif

first.c內容

#include #include "first.h"

void fis_cal(void)

說明:經過這樣的修改,原來的test.c中就包含了count的定義,而first.c中就包含了對count的宣告,重複定義錯誤就得到解決。

結論:這種錯誤原因是「多個c程式都包含了定義全域性變數的標頭檔案」。 

原理分析

我認為「int count;」是對全域性變數的定義,而「extern int count」是對全域性變數的宣告,目的是讓其他檔案也使用這個全域性變數。下邊我們來挖掘全域性變數的定義與宣告的內涵。

全域性變數要麼初始化(非零),要麼沒有初始化(為零)。非零時儲存在程式中的data段,零時儲存在程式的bss段。這談了程式(.bin或者.hex)的結構。我再講一下程式的啟動,程式在啟動(boot)過程中,通常都會執行乙個叫bootloader的引導程式,這個引導程式幹了很多事情,其中有一最重要的任務就是把程式(test段和rodata段)拷貝到記憶體,還包括data段的拷貝和bss段初始化。我們著重講一下data段的拷貝和bss段初始化。

我們的編譯器會為我們定義的全域性變數分配記憶體(位址),而且給我們的全域性變數賦初值(寫記憶體或清零),以後我們的程式就會根據需要來讀這個全域性變數(位址)或者修改這個全域性變數(寫記憶體)。初值為零時就在bss段,這個段初始化**會將這部分清零。初值非零時,初始化**會將全域性變數的初值拷貝到data段。

順便說一下c語言的儲存類說明符,這能幫助我們加深理解。

c語言的儲存類說明符

auto只在塊內變數宣告中被允許, 表示變數具有本地生存期。

extern出現在頂層或塊的外部變數函式與變數宣告中,表示宣告的物件具有靜態生存期, 連線程式知道其名字。

static可以放在函式與變數宣告中,在函式定義時,只用於指定函式名,而不將函式匯出到鏈結程式,在函式宣告中,表示其後邊會有定義宣告的函式,儲存型別static.在資料宣告中,總是表示定義的宣告不匯出到連線程式關鍵字。

一種更好的宣告與定義方式

test.h內容

#ifndef _test_h

#define _test_h

#ifdef globals

int count;

#else

extern int count;

#endif 

#endif

test.c內容

#define globals

#include #include "test.h"

extern void fis_cal(void);

void main(void)

first.c內容

#include #include "test.h"

void fis_cal(void)

說明:這種方法可以只定義乙個標頭檔案實現在不同c檔案中分別實現定義與宣告。「#define globals」只在當前定義的test.c檔案中有效,所以在test.c中#include "test.h"預處理後,加入的是int count,而first.c中加入的"extern int count;"。其實還有一種書寫方法,也能實現這個效果。

test.h內容

#ifndef _test_h

#define _test_h

#ifdef globals

#define ext

#else

#define ext extern

#endif

ext int count;

#endif

C語言全域性變數定義與宣告技巧

在實際的程式設計中,全域性變數對我們程式設計來說既是喜又是淚,雖然說專案中盡量避免使用全域性變數,但總有些時候不得不使用它,並且可能使用得不少,各個模組可能有含有或多或少的幾個全域性變數,而當別的模組需要引用的時候,就必須extern它,造成你定義了一遍又宣告了一遍,這樣就稍顯得麻煩。下面介紹一種全...

C 全域性變數的宣告與定義

1.header1.h中宣告全域性變數,header1.cpp中定義全域性變數 header1.h ifndef header1 h define header1 h extern int g n 標頭檔案中必須加extern宣告全域性變數,不賦值 int g o 錯誤 int g o 10 錯誤 ...

全域性變數的定義宣告

c 中定義全域性變數要注意的地方 yandaren 1220 chinaunix部落格 c 中定義全域性變數要注意的地方 在c 中定義全域性變數是應該盡量在.cpp檔案中定義,而不要在.h 檔案中 定義,定義好了之後,可以在.件中利用 extern關鍵字進行 宣告.如果在.件中定義的話,多層包含可能...