資料的儲存型別
一、變數的作用域
變數的作用域是指變數有效性的範圍,與變數定義的位置密切相關,作用域是從空間這個角度來描述變數的,按照作用域的不同,變數可分為區域性變數和全域性變數。
1、區域性變數
在函式(或**塊)內部定義的變數,也稱為內部變數,區域性變數只能在定義它的函式(或**塊)內使用,其他函式均不能使用,區域性變數的作用域,限於說明它的**塊內:從說明的地方開始至所在的**塊結束。注意,在同乙個作用域內,不允許有同名的變數。
例如:在同乙個main()函式中,定義了三個資料型別和變數名均相同的區域性變數i。在訪問這些變數i中,他們不會混淆,它們是三個不同的區域性變數。它們各有自己的作用域。
**如下:
#include
void main()
else
printf("the i in main() still is %d\n",i);
return;
}執行結果:
2、全部變數
作用域是從定義點開始直到程式檔案結束的變數,稱為全域性變數。全域性變數在程式的整個執行過程中,都占用儲存單元。在乙個函式中改變了全域性變數的值,其他函式可以共享。全域性變數相當於起到在函式間傳遞資料的作用。
例如:求一元二次方程的根:ax2 + bx + c =0
**如下:
#include
#include
float x1,x2,p,q,d; //定義全域性變數
void greater_than_zero(float,float); //函式宣告
void equal_to_zero(float,float);
void smaller_than_zero(float,float);
void main()
else if(d==0)
else
return;
}void greater_than_zero(float x,float y)
void equal_to_zero(float x,float y)
void smaller_than_zero(float x,float y)
二、變數的儲存型別
執行程式時,系統在記憶體中為資料的儲存開闢了兩塊區域:靜態資料區和動態資料區,分配在靜態資料區的變數稱為靜態變數,分配在動態資料區的變數稱為動態變數。在靜態和動態兩大類的儲存方法中,c語言將變數的儲存型別分為四種,其儲存型別說明符和名稱如下:
型別說明符 名稱
auto 自動變數
static 靜態區域性變數
extern 外部變數
register 暫存器變數
在變數定義語句中,儲存型別符放在它所修飾的資料型別前面,一般形式為:
儲存型別符 資料型別符 變數名錶;
1、自動變數auto(動態儲存型別)
在函式內定義的或在函式的語句塊內定義的變數,若儲存型別省略或寫為auto,都是自動變數。此前的程式中使用的都屬於自動變數。下面的兩條變數的定義語句是等價的:
int a,b; 等價於:
auto int a,b;
注意:自動變數在初始化前,或沒有賦值前,它的值是不確定的。
2、靜態區域性變數static(靜態儲存型別)
靜態區域性變數在靜態儲存區為其分配儲存空間,在整個程式執行期間都不釋放,變數的生存期是程式執行期。雖然靜態區域性變數的儲存空間在整個程式執行中都保持著,但是,在它的作用域以外,仍然是不能被引用的。
例如:函式numbers()是乙個數發生器,每呼叫函式numbers()一次,產生乙個整數。每個數的產生都是在上次產生的數的基礎上計算出來的。
**如下:
#include
int numbers(void);
main()
int numbers(void)
執行結果:
3、暫存器變數register()
如果變數在程式執行中使用非常頻繁,則為訪問該變數要消耗很多時間。利用暫存器操作速度快的特點,將變數存放在cpu的暫存器中,可以提高程式的執行效率。暫存器變數占用cpu的高速暫存器,不占用記憶體單元。變數的值就儲存在cpu的暫存器中。
暫存器變數僅能用於定義區域性變數或是函式的形參,不能用於全域性變數。在ansi中,暫存器變數可以用於任何資料型別,但turbo c++將暫存器變數只限用於char型和int型變數。
例如:register int num;
register型變數常用於作為迴圈控制變數,這是使用它的高速特點的最佳場合。比較下面兩個程式的運算速度。
main ( )
#include
main( )
三、全域性變數的儲存定義
1、外部全域性變數
全域性變數是在函式外部定義的變數。變數在編譯時分配在靜態資料區,生存期是程式的執行期間。作用域是從定義點往後的所有定義的函式均有效。但當函式內的區域性變數同名時,區域性變數是有效的,全域性變數無效。
如果在乙個原始檔中將某些變數定義為全域性變數,而這些全域性變數允許其他原始檔中的函式引用的話,就需要有一種方法,把程式的全域性變數告訴相關的模組檔案。解決的辦法是,在乙個模組檔案中將變數定義為全域性變數,而在引用這個變數的模組檔案中,用儲存型別符extern將其說明為外部變數。即extern定義符的作用只是將乙個檔案定義全域性變數的作用域延伸到本源程式檔案。
例如:檔案file1定義主函式和乙個全域性變數m。檔案file2定義計算階乘的函式fact(),並說明變數m為外部的。
#include
int fact(void);
int m;
void main()
extern int m;
int fact(void)
2、靜態全域性變數
靜態全域性變數是在被定義的源程式檔案以外是不可見的。也就是說,靜態全域性變數只限於它所在的源程式檔案中的函式引用,而不能被其他的源程式檔案中的函式引用。其定義形式和區域性靜態變數是一樣的,其一般形式為:
static 資料型別 變數;
注意:(1)靜態全域性變數和靜態區域性變數分配在靜態資料區,生存期是程式執行期。但靜態全域性變數與靜態區域性變數的作用域方面是不相同的;
(2)靜態全域性變數和全部變數在同一檔案內的作用域是一樣的,但全域性變數的作用域可延伸到其他程式檔案;
(3)靜態區域性變數與(動態)區域性變數在作用域上相同的,但前者分配在靜態資料區,後者分配在動態資料區,因而,他們的生存期是不同的。
//第乙個檔案file1.c
static int num1,num2;
int numbers(void)
void num_init(int x1,int x2)
#include
#include "file1.c"
int numbers(void);
void num_init(int,int);
main(void)
總結:(1)乙個資料報含有兩方面的屬性:資料型別和儲存型別;
(2)從作用域的角度,有區域性變數和全域性變數,按儲存型別分,區域性變數又分為自動的、靜態的、暫存器三種;全域性變數又分為靜態的和外部的兩種;
(3)從生存期的角度,有動態儲存和靜態儲存兩類,動態儲存類的資料分配在動態資料區,是在進入相應的定義塊時分配儲存單元,如自動變數、暫存器變數和形參;靜態儲存類的資料分配在靜態資料區,是編譯時分配的,在整個程式執行期間都存在,如靜態區域性變數、靜態外部變數和全域性變數。
四、內部函式和外部函式
對於乙個多源程式檔案的c程式來說,根據乙個函式能否呼叫其他源程式檔案的函式,將函式分為內部函式和外部函式。
1、內部函式
函式只能被源程式檔案的函式所呼叫,這樣的函式稱為內部函式,內部函式也叫做靜態函式,內部函式在定義時,要在函式型別前加上說明符static,例如:
static char myfunction(char ch)
如果在定義函式時省略extern,則隱含為外部函式。例如:
void num_init(){}
int numbers(){}
在定義時雖然沒有用extern說明,但實際上就是外部函式,它們可以被另乙個檔案的函式呼叫。在需要呼叫外部函式的檔案中,用extern說明所用的函式是外部函式。例如:
extern int sum();
#include
#include "file4.c"
int sum();
int i,j;
main()
區域性變數與全域性變數
根據c語言的說法,區域性變數 定義在方法內部的變數叫區域性變數 全域性變數 定義在方法外部的變數叫全域性變數。區域性變數和全域性變數的主要區別在於二者的生存週期不同。全域性變數的生存週期 靜態分配記憶體,程式執行期間常駐記憶體,直到程式執行結束。區域性變數的生存週期 動態分配記憶體,位於執行緒堆疊中...
全域性變數與區域性變數
區域性變數 在區域性 塊內定義 作用域在區域性 塊內,生命週期在區域性 塊內,結束時銷毀。include void test int main return 0 輸出 1111111111 全域性變數 在所有 塊外定義 作用域是整個工程,生命週期程式開始至結束。工程test 10 10 原始檔sum...
區域性變數與全域性變數
在乙個函式內部定義的變數,它只在本函式範圍內 有效,也就是說只有在本函式內才能使用它們,在 此函式以外是不能使用這些變數的。在函式之外定義的變數是外部變數,稱為全域性變 量 global variable,也稱全程變數 全域性變數的有效範圍為從定義變數的位置 開始到本原始檔結束。includeusi...