標籤:編譯器 c語言 程式員 空間 源檔案 變數
------- IOS培訓期待與您交流! ----------
一、變數
變數代表著一個有名字的、具有特定屬性的一個儲存單元,運行期間,變數的值是可以改變的。變數必須先定義,後使用。定義時,指定該變數的名字與類型。變數名實際上是以一個名字代表的一個儲存地址;而從變數中取值,實際上是通過變數名找到相對應的記憶體位址,再從該儲存單元中讀取相對應的資料。
剛剛提到了變數定義這個詞,我們知道,在定義函數的時候,我們都會先對函數進行一個聲明,這就又引用了一個概念:聲明。那麼我們先來理解一下什麼是聲明和定義:例如:聲明一個變數意味著向編譯器描述變數的類型,但並不為變數分配儲存空間,但是定義一個變數意味著在聲明變數的同時還要為變數分配儲存空間,而在定義一個變數的同時還可以對這個變數進行初始化的操作。
我們可能會在下列3種情況下定義變數:
(1)在函數的開頭定義;
(2)在函數內的複合陳述式中進行定義;
(3)在函數的外部進行定義
從變數的範圍的角度上來說,變數通常可分為:局部變數以及全域變數
(1)局部變數通常只定義不聲明,而全域變數多在源檔案中定義,在標頭檔中聲明;
(2)局部變數可理解為:在一個函數的內部定義的變數是內部變數,它只在本函數範圍內有效。不同的函數中可以使用同名的局部變數,它們代表著不同的對象,互不干擾。
(3)全域變數可理解為:在函數之外定義的變數稱為外部變數,外部變數是全域變數,它可以為本檔案中其他函數所共用,全域變數在程式的全部執行過程中都佔用儲存單元,這樣會減低程式的運行速度,並且也會使函數的通用性降低等等,因此,盡量少使用全域變數。
若是從變數值存在的時間(即生存期)來說的話,變數的儲存有兩種不同的方式:靜態儲存方式和動態儲存裝置方式,C的存類別分為4種,分別是:自動的(auto)、靜態(static)、寄存器的(register)、外部的(extern)
(1)自動變數(auto變數):函數中的局部變數,其預設格式是自動變數類型。
例如,在函數體中
int b, c=3; auto int b, c=3;
這兩局代碼其實是等價的。
自動變數是動態分配儲存空間的,函數結束後就釋放。自動變數如不賦初值,則它的值是一個不確定的值。
(2)靜態局部變數(static局部變數):靜態局部變數是指在函數體內聲明和定義的局部變數,它僅供本函數使用,即其他函數不能調用它。靜態局部變數的值在函數調用結束後不消失而保留原值,即其佔用的儲存單元不釋放,在下一次函數調用時,該變數已有值,就是上一次函數調用結束時的值。
靜態局部變數在靜態儲存區配置儲存單元,在程式的整個運行期間都不釋放。靜態局部變數是在編譯時間賦初值的,即只賦初值一次。
在SDT編譯器中,建議對靜態局部變數賦初值,否則該靜態局部變數的初值為不確定值。在其他編譯器中,未初始化的靜態局部變數的初值可能為零,這由具體的編譯器所決定,使用前最好測試一下。
(3)寄存器變數(register變數):帶register修飾符的變數暗示(僅僅是暗示而不是命令)編譯器本變數將被頻繁使用,如果可能的話,應將其保留在CPU的寄存器中,以加快其存取速度。
對於現有的大多數編譯器,最好不要使用register修飾符。因為它是對早期低效的C編譯器的一個很有價值的補充。隨著編譯器技術的進步,在決定哪些變數應當被存到寄存器中時,現在的C編譯器能比程式員做出更好的決定。
(4)外部變數(extern全域變數):定義函數中的全域變數時,其預設格式是外部變數類型。外部變數應該在一個標頭檔中聲明,在當前源檔案中定義。外部變數允許其他檔案引用。
下例聲明了一個變數和一個結構,定義了兩個變數,其中一個定義帶初始化:
extern int decl1; // this is a declarationstruct decl2{ int member;}; // this just declares the type – no variable mentionedint def1 = 8; // this is a definitionint def2; // this is a definition
二、函數
從本質意義上來說,函數就是用來完成一定的功能的,一個C語言程式可由一個主函數和若干個其他函數組成。而在程式中使用到的所有函數,同樣必須先定義,後使用,今天關於函數的定義以及使用的知識在這裡就不詳細說明啦,主要講的是內建函式與外部函數的區別與使用。
(1)內建函式:內建函式的聲明和定義多在當前源檔案中完成;而外部函數通常在源檔案中定義,在標頭檔中聲明。
格式:
static 類型名 函數名(形參表);例如:static int fun(int a , int b);
只在當前源檔案中使用的函數應該說明為內建函式。內建函式應該在當前源檔案中聲明和定義。若內建函式在標頭檔中聲明,其他源檔案通過包含這個標頭檔也可使用這個函數,但這樣就失去了其做為內建函式的意義。
優點:使用內建函式,可以使函數只局限於所在檔案。這避免了與其他源檔案中可能出現的同名函數發生衝突。
例:
File: function1.c#include “function1.h”static int stat_func(void);void MasterFunction(void){…rc = stat_func( );…}static int stat_func(void){ …return rc;}
(2)外部函數
格式:
extern 類型名 函數名(形參表);例如:extern int fun(int a , int b);
對於可在當前源檔案以外使用的函數,應該在一個標頭檔中聲明。其他源檔案可通過包含這個標頭檔或進行聲明來使用這些函數(推薦用前者)。
一個良好的編程習慣是在標頭檔中聲明函數的原型。這可方便編譯器查錯。定義函數時,預設的函數類型是外部函數。如:
void fun2(void); extern void fun2(void);
其函數類型是等價的,但前一個是定義函數,後一個是聲明函數。
小結
編寫程式,尤其是大型程式時,建議採用上文所述的方法對不同的變數、函數進行必要的聲明、定義。做好這些細節上的事務,可以為您的編程、調試、移植等帶來很大的方便。
黑馬程式員--C語言基礎之--變數、內建函式與外部函數