關於變數的宣告和定義
一個函式一般由兩部分組成:宣告部分和執行語句。宣告部分的作用:是對有關的識別符號(如變數、函式、結構體、共用體等)的屬性進行宣告。對於函式而言,宣告和定義的區別是明顯的,函式的宣告是函式的原型,而函式的定義是對函式功能的定義。對被呼叫函式的宣告是放在主調函式的宣告部分中的,而函式的定義顯然不在宣告部分的範圍內的,它是一個獨立的模組
對變數而言,宣告與定義的關係稍微複雜一些。在宣告部分出現的變數有兩種情況:
- 需要建立儲存空間的,此為定義性宣告,簡稱定義
- 不需要建立儲存空間的,此為引用性宣告
廣義的說,宣告包括定義,但並非所有的宣告都是定義。例如 int a;
,既是宣告,也是定義;而對extern a;
而言,是宣告而不是定義。一般為了敘述方便,把建立儲存空間的宣告稱定義,而把不需要建立儲存空間的宣告稱為宣告。顯然這裡指的宣告是狹義的,即非定義性宣告。
外部變數定義和外部變數宣告的含義是不同的。外部變數的定義只能有一次,它的位置在所有函式之外。在同一檔案中,可以有多次對同一外部變數的宣告,它的位置可以在函式內(哪個函式要用就在哪個函式中宣告),也可以在函式之外(在外部變數的定義點之前)。系統根據外部變數的定義(而不是根據外部變數的宣告)分配儲存單元。對外部變數的初始化只能在“定義”時進行,而不能在“宣告”中進行。所謂“宣告”,其作用是宣告該變數是一個已在其他地方已定義的外部變數,僅僅是為了擴充套件改變數的作用範圍而作的“宣告”
在函式中出現對變數的宣告(除了用 extern 宣告的以外)都是定義。在函式中對其他函式的宣告不是函式的定義
內部函式和外部函式
函式本質上是全域性的,因為定義一個函式的目的就是要被另外的函式呼叫。如果不加宣告的話,一個檔案中的函式既可以被檔案中的其他函式呼叫,也可以被其他檔案中的函式呼叫。但是,也可以指定某些函式不能被其他檔案呼叫。根據函式能否被其他原始檔呼叫,將函式區分為內部函式和外部函式
內部函式
如果一個函式只能被本檔案中的其他函式所呼叫,它稱為內部函式
在定義內部函式時,在函式名和函式型別的前面加static
,即:
static 型別名 函式名(形參表);
內部函式又稱為靜態函式,因為它是用 static
宣告的。
使用內部函式,可以使函式的作用域只侷限於所在檔案。這樣子,在不同的檔案中即使有同名的內部函式,也互不干擾。這就使它對外界“遮蔽”了
通常,一個大程式往往分工由不同的人分別編寫不同的檔案模組,在各人編寫自己的檔案模組時,不必擔心所用函式是否會與其他檔案模組中的函式同名
通常把只能由本檔案使用的函式和外部變數放在檔案開頭,前面都冠以 static 使之區域性化,其他檔案不能引用。這就提高了程式的可靠性。
外部函式
如果在定義函式時,在函式的首部的最左端加關鍵字 extern
,則此函式是外部函式,可供其他檔案呼叫
extern 函式型別 函式名(形參列表)
C語言規定,如果在定義函式時省略 extern
,則預設為外部函式
在需要呼叫此函式的其他檔案中,需要對此函式作宣告(不要忘記,即使在本檔案中呼叫一個函式,也要用函式原型進行宣告)。在對此函式作宣告時,要加關鍵字 extern
,表示該函式“是在其他檔案中定義的外部函式”
使用 extern
宣告就能夠在本檔案中呼叫在其他檔案中定義的函式,或者說把該函式的作用域擴充套件到本檔案中
extern
宣告的形式就是在函式原型基礎上加關鍵字 extern
由於函式本質上是外部的,在程式中經常要呼叫其他檔案中的外部函式,為方便程式設計,C語言允許在宣告函式時省寫 extern
用函式原型能夠把函式的作用域擴充套件到定義該函式的檔案之外(不必使用 extern
)。只要在使用該函式的每一個檔案中包含該函式的函式原型即可。函式原型通知編譯系統:該函式在本檔案中稍後定義,或在另一檔案中定義。
利用函式原型擴充套件函式作用域最常見的例子是 #include
指令的應用。在#include
指令所指定的“標頭檔案”中包含呼叫庫函式所需的資訊