局部變量和全局變量
每一個變量都有其有效作用范圍,這就是變量的作用域,在作用域以外是不能訪問這些變量的。
局部變量
在一個函數內部定義的變量是局部變量,它只在本函數范圍內有效,也就是說只有在本函數內才能使用他們,在此函數以外是不能使用這些變量的。
同樣,在復合語句中定義的變量只在本復合語句范圍內有效,這些內部變量稱為局部變量。
需要注意的是
1、主函數main中定義的變量也只在主函數中有效,不會因為在主函數中定義而在整個文件或程序中有效,在主函數中也不能使用其它函數中定義的變量。
2、不同函數中可以使用同名變量,他們代表不同的對象,互不干擾。
3、可以在一個函數內的復合語句中定義變量,這些變量只在本復合語句中有效,這種復合語句也稱為分程序或程序塊。
4、形式參數也是局部變量。
5、在函數原型中出現的參數名,并不是實際存在的變量,不能被引用,編譯系統對函數聲明中的參數名是忽略的,即使在調用函數時也沒有為他們分配存儲單元。
全局變量
在函數內部定義的變量是局部變量,而在函數外部定義的變量是外部變量,也稱全局變量。全局變量的有效范圍為從定義變量的位置開始到本源文件結束。
在一個函數中既可以使用本函數中定義的局部變量,又可以使用有效的全局變量。
需要注意的是
1、全局變量的作用是增加了函數間數據聯系的渠道。由于同一文件中的所有函數都能使用全局變量的值,因此如果在一個函數中改變了全局變量的值,就能影響到其它函數,使其它函數中的同名變量的值也同時改變,這相當于各個函數間有直接的傳遞通道。由于函數的調用只能帶回一個返回值,因此有時可以利用全局變量增加函數間數據傳遞的渠道。
2、不必要時不要使用全局變量。因為全局變量在程序的全部執行過程中都占用存儲單元,而不是僅在需要時才開辟單元。全局變量使函數的通用性降低了,因為在執行函數時要受到外部變量的影響。如果將一個函數移到另一個文件中,還要將有關的外部變量及其值一起移過去,若該外部變量與其它文件的變量同名,就會出現問題,降低了程序的可靠性和通用性。
在程序設計中,在劃分模塊時要求模塊的內聚性強、與其它模塊的耦合性弱,即模塊的功能要單一,與其它模塊的相互影響要盡量少。
一般要求把程序中的函數做成一個封閉體,除了可以通過實參-形參的渠道與外界發生聯系外,沒有其它渠道,這樣的程序移植性好,可讀性強。
使用全局變量過多,會降低程序的清晰性,人們往往難以清楚地判斷出每個瞬間各個全局變量的值。在各個函數執行時都可能改變全局變量的值,程序容易出錯。
3、如果在同一個源文件中,全局變量與局部變量同名,則在局部變量的作用范圍內,全局變量被屏蔽,會不起作用,此時可以使用局部變量。
4、變量的有效范圍稱為變量的作用域。變量有四種不同的作用域,分為文件作用域、函數作用域、塊作用域和函數原型作用域。文件作用域是全局的,其它作用域是局部的。
變量的聲明和定義
對變量而言,在聲明部分出現的變量有兩種情況,一種是需要建立存儲空間的,如int a;,稱為定義性聲明,或稱為定義。另一種是不需要建立存儲空間的,如extern int a;,稱為引用性聲明。
廣義來講,聲明包括定義,但并非所有的聲明都是定義。一般為了敘述方便,把建立存儲空間的聲明稱為定義,把不需要建立存儲空間的聲明稱為聲明。這里指的聲明是狹義的,即非定義性聲明。
外部變量定義和外部變量聲明是不同的。外部變量的定義只能有一次,它的位置在所有函數之外,而同一文件中的外部變量的聲明可以有多次,它的位置可以在函數之內,也可以在函數之外。系統根據外部變量的定義分配存儲單元。對外部變量的初始化只能在定義時進行,而不能在聲明時進行。
所謂聲明,其作用是向編譯系統發出一個信息,聲明該變量是一個在后面定義的外部變量,僅僅是為了提前引用該變量而作的聲明。
需要注意的是,使用auto,register,static聲明變量時,是在定義變量的基礎上加上這些關鍵字,而不能單獨使用。
內部函數和外部函數
函數本質上是全局的,因為一個函數要被另外的函數調用,但是也可以指定函數只能被本文件調用,而不能被其它文件調用。根據函數能否被其它源文件調用,將函數區分為內部函數和外部函數。
內部函數
如果一個函數只能被本文件中其它函數所調用,則稱為內部函數。
在定義內部函數時,在函數名和函數類型的前面加static。
函數首部的一般格式為
static 類型標識符 函數名(形參表)
內部函數又稱靜態函數,使用內部函數,可以使函數只局限于所在文件。如果在不同的文件中有同名的內部函數,互不干擾。這樣不同的人可以分別編寫不同的函數,而不必擔心所有函數名是否會與其它文件中的函數相同。通常把只能由同一文件使用的函數和外部變量放在一個文件中,在它們之前都冠以static使之局部化,其它文件不能引用。
外部函數
1、在定義函數時,如果在函數首部的左端冠以關鍵字extern,則表示此函數是外部函數,可供其它文件調用。如果在定義函數時省略extern,則默認為外部函數。
2、在需要調用此函數的文件中,用extern聲明所用的函數是外部函數。
使用extern聲明就能夠在一個文件中調用其它文件中定義的函數,或者說把該函數的作用域擴展到本文件。
extern聲明的形式就是在函數原型基礎上加關鍵字extern。由于函數在本質上是外部的,在程序中經常要調用其它文件中的外部函數,為方便編程,C++允許在聲明函數時省寫extern。
用原型函數能夠把函數的作用域擴展到定義該函數的文件之外,只要在使用該函數的每一個文件中包含該函數的函數原型即可。函數原型通知編譯系統,該函數在本文件中稍后定義,或在另一個文件中定義。
頭文件
頭文件的內容
頭文件一般包含:對類型的聲明、函數聲明、內置函數的定義、宏定義、全局變量定義、外部變量聲明或其它頭文件
由于有了#include指令,就可以把不同的文件組合到一起,形成一個文件,因此說,頭文件是源文件之間的接口。
關于C++標準庫和頭文件的形式
新的C++標準庫中的頭文件不再包括后綴.h,但為了使大批已有的C程序能繼續使用,許多C++編譯系統保留了C的頭文件。建議盡量使用符合C++標注的形式。
如果用戶自己編寫頭文件,可以使用.h作后綴,便于區分哪些頭文件使屬于C++標準庫的,哪些頭文件使用戶自編或別人提供的。