關於C語言中的變數

2022-08-10 23:54:12 字數 3011 閱讀 1193

//#include <>

void f5(int);

static int e;

void f4(int a)

void main()

// void f4(int);

int e;

void f5(int b)

首先,main函式中以10為引數呼叫函式f5,在函式f5中,給變數e賦值為5,接下來呼叫函式f4,引數b的值為10,在函式f4中給變數e賦值為引數a的值10,注意:此e非彼e。我們先來看一看變數e在兩個檔案中的定義,唯一的區別就是檔案中多了乙個關鍵字:

static。然而就是這個static使得中的變數e變成了區域性變數,換句話說這個變數e的作用域已經不是全域性的了,它的作用範圍值在這個檔案中有效,在中它是不起作用的。因此不難看出,這個程式的結果是:

e = 5

當然,如果想要使變數e作用域是全域性的,程式可修改如下:

// #include <>

void f5(int);

int e;

void f4(int a)

void main()

// void f4(int);

extern int e;

void f5(int b)

檔案中的int e前面多了乙個關鍵字:extern,表明這個變數是外部的,而且,

extern int e;

不是變數的定義,它只是宣告乙個變數,定義和宣告的區別我們將在下面介紹。修改以後的程式執行結果是:

e = 10

在實際的工作中,我們都應該盡量少的使用全域性變數,尤其在乙個多人共同編碼的專案中,每個人負責一部分**的編寫,有可能造成全域性變數命名的衝突,當要在乙個檔案中使用乙個該檔案內多個函式都要用到的變數時,應在該變數定義前面加上關鍵字:static,使得該變數只在本檔案內有效,避免和其他人命名的變數名衝突。

第三、 變數的定義和宣告

一般情況下,在c程式中變數的定義和宣告是合二為一的,如:

int a;

我們一般稱之為變數的定義,這一點上,不如函式來的明顯。當我們確實想宣告乙個變數的時候,我們用以下語句來完成:

extern int a;

關鍵字extern表示變數是外部的,換句話說,這裡只是宣告該變數的存在,以便在程式中使用,而變數的定義可以在其他檔案,也可以在本檔案內部,如:

#include <>

extern int a;

void main()

int a = 5;

在這段**中,如果沒有上面的extern int a;這句話對變數a的宣告,則在main函式中使用變數a則是非法的,因為編譯程式在編譯的時候沒有找到a的定義;相反,如果沒有下面的這句int a = 5;雖然程式能夠通過編譯,但是連線(link)的時候也會出現錯誤,提示沒有找到變數a的定義。

變數的定義和宣告最重要的區別就是定義變數的時候要為變數分配儲存空間,而宣告乙個變數則不需要。因此,extern int a;這個語句並沒有為變數a分配記憶體空間,如果沒有變數a的定義,那麼任何對變數a的操作都是非法的,因為這個變數還不存在。

變數的定義和宣告另乙個區別就是定義變數是可以給變數賦初值,如:

int a = 5;

而宣告則不可以,如:

extern int a = 5; // 錯誤

這個錯誤顯而易見,因為這個5沒有儲存的空間。

第四、 變數的儲存空間

簡單的說,在函式中定義的變數一般情況下都在棧(stack)中,除非你把變數定義成static型的,此時,他和其他在函式外面定義的變數一樣,都分配在全域性記憶體中。例如:

#include <>

int a, b;

static int c;

main()

在上面的程式中,變數a、b、c、d都是儲存於全域性記憶體中的,而變數e則是儲存於棧中。由於函式執行結束之後,會進行還原棧的動作,因此在函式內部定義的變數的儲存空間在函式返回以後就不再保留了。

所以,我們會看到需要保留函式內變數的值的時候,一般都把變數定義成static型別,此時變數儲存於全域性記憶體中,當函式的佔被還原的時候,變數的值還存在,也就是這個道理了。

第五、 變數的初始化

變數的初始化對於大家都是相當熟悉了,形式也比較簡單:

int a = 5;

這就是最簡單的初始化語句了,如果是下面的語句:

int a;

那麼大家知道變數a的預設初始值是多少嗎?答案是不確定。當然不是說a的預設值是任意值,而是說變數變數a定義的位置、作業系統以及和使用的編譯器相關。

例如,在windows平台上使用vc++6.0編譯程式,如果int a;出現在所有函式的外面,那麼a的預設初始值就是0,但是如果int a;出現在函式的裡面,那麼一般情況下a的預設初始值就是0xcc,大家會比較奇怪,為什麼微軟會使用這麼奇怪的初始值呢?我想因為此時a在棧中被分配,二戰是不應該被破壞的,如果有非法的語句莫名其妙的跳到這裡來執行的話,0xcc是彙編語句中的(int 3)的二進位制**,所以程式就會中斷執行,防止不可預料的結果發生。

但是在linux平台上,變數的預設初始值一般都是0。

因此,但我們在寫程式的時候,要養成為變數新增初始值的好習慣。

我們再談一談陣列的初始化,

char a[100];

char a[100] = ;

這兩條語句都是定義乙個字元陣列,第二條語句是對陣列進行了初始化。下面我們來討論乙個有意思的話題,就是這兩條語句對編譯連線以後的可執行檔案的大小有什麼影響?

當然了,如果陣列的初始化是在函式中,則影響不明顯,但是在所有函式的外面定義的話就不一樣了,不信你可以試試下面的程式:

#include <>

char [100000000] = ;

void main()

編譯的時候你可要先確認一下你的磁碟剩餘空間呀,如果少於100m那麼請勿試驗,否則後果自負!說到這裡你應該明白了吧,編譯連線以後的可執行檔案有100多m呀,嚇人吧!其實這是由於在windows平台上的可執行檔案的格式所決定的,有興趣的朋友可以研究一下windows的pe檔案的結構。

以上我們討論了c語言中關於變數的一些小問題,也是我在實際工作和學習中遇到了,當然其中不免有一些錯誤,希望你能告訴我,我將非常高興。

C語言中static變數使用方法

1.static 變數 靜態變數的型別說明符是static。靜態變數當然是屬於靜態儲存方式,但是屬於靜態儲存方式的量不一定就是靜態變數。例如外部變數雖屬於靜態儲存方式,但不一定是靜態變數,必須由 static加以定義後才能成為靜態外部變數,或稱靜態全域性變數。2.靜態區域性變數 靜態區域性變數屬於靜...

C語言中static變數使用方法

1.static 變數 靜態變數的型別說明符是static。靜態變數當然是屬於靜態儲存方式,但是屬於靜態儲存方式的量不一定就是靜態變數。例如外部變數雖屬於靜態儲存方式,但不一定是靜態變數,必須由 static加以定義後才能成為靜態外部變數,或稱靜態全域性變數。2.靜態區域性變數 靜態區域性變數屬於靜...

關於C語言中的結構體對齊

1 什麼是位元組對齊 乙個變數占用 n 個位元組,則該變數的起始位址必須能夠被 n 整除,即 存放起始位址 n 0,對於結構體而言,這個 n 取其成員種的資料型別佔空間的值最大的那個。2 為什麼要位元組對齊 記憶體空間是按照位元組來劃分的,從理論上說對記憶體空間的訪問可以從任何位址開始,但是在實際上...