




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
在前面幾章中,我們已用到各類存儲變量,并作過相應(yīng)的簡單說明。為了避免使讀者掌握過多的概念而影響編程和閱讀,在那里所作的描述是十分有限的。為了使讀者對C語言變量的存儲類別有比較深入的了解,這里作一些詳盡的討論。在C語言中,變量不僅具有數(shù)據(jù)類型,而且還區(qū)分存儲類別。變量在使用之前其數(shù)據(jù)類型必須加以說明,而存儲類別則可缺省說明或顯式說明。顯式說明指直接在變量說明前加上存儲類型標(biāo)志,如auto、register、static、extern等。在缺省說明時,編譯程序假設(shè)所要求的存儲類別隱含在上下文中。變量的存儲類別既說明了變量的存儲單元,又說明了變量的“活動”時間和作用域。
第五章變量的存儲類別和作用域
從變量的作用域(即從空間)角度來分,可以將變量分為全局變量和局部變量。從另一個角度,即從變量存在的時間(即生存期)角度來分,可以分為靜態(tài)存儲變量和動態(tài)存儲變量。動態(tài)數(shù)據(jù)存儲在內(nèi)存的堆棧區(qū),靜態(tài)數(shù)據(jù)存儲在內(nèi)存的固定存儲區(qū),即靜態(tài)存儲區(qū)。全局變量存儲在內(nèi)存的固定存儲去,局部變量存儲在內(nèi)存的堆棧區(qū)。靜態(tài)存儲變量在程序運行期間分配固定的存儲空間。動態(tài)存儲變量在程序的運行過程中根據(jù)需要動態(tài)分配存儲空間。圖5-1是內(nèi)存中供用戶使用的存儲空間的分配情況。
5.1
變量的類別概述
存儲空間可以分為三部分:l
程序區(qū)。l
靜態(tài)存儲區(qū)。l
動態(tài)存儲區(qū)。數(shù)據(jù)存放在靜態(tài)存儲區(qū)和動態(tài)存儲區(qū)中。全局變量存放在靜態(tài)存儲區(qū)中,在程序執(zhí)行過程中它們占據(jù)固定的存儲單元,程序執(zhí)行完畢才釋放,而不是動態(tài)地分配和釋放。在C語言中每一個變量有兩個屬性:數(shù)據(jù)類型和存儲類別。對數(shù)據(jù)類型,讀者已熟悉(如整型,字符型等)。存儲類別指的是數(shù)據(jù)在內(nèi)存中存儲的方法。存儲方法分為兩大類:靜態(tài)存儲類和動態(tài)存儲類。具體包含四種:自動的(auto)、靜態(tài)的(static)、寄存器的(register)、外部的(extern)。下面將就前面所提及的所有變量依次向讀者作一下介紹。
5.1
變量的類別概述
5.2局部變量
在一個函數(shù)內(nèi)或復(fù)合語句中定義的變量稱為內(nèi)部變量。它只在本函數(shù)范圍或復(fù)合語句內(nèi)有效,也就是說只有在本函數(shù)或復(fù)合語句內(nèi)才能使用它們,否則是不能使用這些變量的。內(nèi)部變量又稱為“局部變量”。注意:復(fù)合語句以左花括號({)開始至右花括號(})結(jié)束?;ɡㄌ栔锌梢杂腥我舛鄺l語句,也可以沒有語句?;ɡㄌ栔羞€可以有變量定義語句。包括變量定義語句的復(fù)合語句成為分程序,我們這里把它統(tǒng)稱為復(fù)合語句。
【例5.1】局部變量例程
floatfl(a)/*函數(shù)fl()*/inta;
{intb,c;形參a和局部變量b、c有效范圍
}charf2(x,y)/*函數(shù)f2()*/intx,y:
{inti,j;形參x,y和局部變量i、j有效范圍
}main()/*主函數(shù)*/{intm,n;局部變量m和n有效范圍
}
5.2局部變量
這里,對局部變量作如下說明:(1)主函數(shù)main()中定義的變量(m和n)只在主函數(shù)中有效,而不因為在主函數(shù)中定義就會在整個文件或程序中有效,這是和PASCAL語言不同的。主函數(shù)也不能使用其他函數(shù)中定義的變量。(2)不同函數(shù)中可以使用相同名字的變量,它們代表不同的對象,互不干擾。例如,在f1()函數(shù)中定義了變量b和c,倘若在f2()函數(shù)中也定義變量b和c,它們在內(nèi)存中占不同的單元,互不混淆。(3)形式參數(shù)也是局部變量。例如f1()函數(shù)中的形參a,也只在函數(shù)f1()中有效。其他函數(shù)不能調(diào)用。(4)在一個函數(shù)內(nèi)部,可以在語句塊(復(fù)合語句中)定義變量,這些變量只在該語句塊(復(fù)合語句)中有效,這種語句塊(復(fù)合語句)也可稱為“分程序”或“程序塊”。
5.2局部變量
【例5.2】下列程序中,具有相同變量名的變量出現(xiàn)在三個層次中。main(){intx=1;/*最外層變量初始化并賦值1*/{intx=2;/*第二層變量初始化并賦值2*/{intx=3;/*第三層變量初始化并賦值3*/printf("%d\n",x);
}printf("%d\n",x);
}printf("%d\n",x);}輸出結(jié)果:
3215.2局部變量
【例5.3】如果外層、中層的變量x不賦值,則它們的值是不確定的。main(){intx;
{intx;
{intx=3;
printf("%d\n",x);}printf("%d\n",x);
}printf("%d\n",x);}輸出結(jié)果:
308500和850是程序運行時輸出的不定結(jié)果,為隨機數(shù)。
5.2局部變量
5.3全局變量5.3.1全局變量及其定義和作用范圍在函數(shù)內(nèi)定義的變量是局部變量,而在函數(shù)外定義的變量稱為外部變量,外部變量是全局變量。全局變量可以為本文件中其他函數(shù)所共用。它的有效范圍:從定義變量的位置開始到本源文件結(jié)束。如:
intp=1,q=5;/*外部變量*/floatf1(a)/*定義函數(shù)f1*/inta;
{intb,c;
}charc1,c2;/*外部變量*/charf2(x,y)/*定義函數(shù)f2*/intx,y;
{inti,j;
}main()/*主函數(shù)*/{intm,n;
}p、q、c1、c2都是全局變量,但它們的作用范圍不同,在main()函數(shù)和函數(shù)f2()中可以使用全局變量p、q、c1、c2,但在函數(shù)f1()中只能使用全局變量p、q,而不能使用c1和c2。在一個函數(shù)中既可以使用本函數(shù)中的局部變量,又可以使用有效的全局變量。
5.3全局變量5.3.2全局變量的有關(guān)說明(1)設(shè)立全局變量增加了函數(shù)間數(shù)據(jù)聯(lián)系的渠道。如果全局變量定義在源文件的前面位置,則由于一個文件中的所有函數(shù)都能引用全局變量的值,因此如果在一個函數(shù)中改變了全局變量的值,就能影響到其他函數(shù),相當(dāng)于各個函數(shù)都有直接的傳遞通道,從函數(shù)得到一個以上的返回值?!纠?.4】voidmul()。
intc;main()
{inta,b;printf("inputaandb:");scanf("%d,%d",&a,&b);mul(a,b);printf("\na*b=%d\n",c);}voidmul(
intx,inty)
{c=x*y;}
5.3全局變量由于本例中定義了一個外部變量c,它在函數(shù)main()和mul()中都是可見的全局變量。在mul()中把x*y的結(jié)果賦給變量c;在main()中直接引用c的值,也就得到了x*y的結(jié)果。因此,函數(shù)mul()中也不需要用return語句來返回函數(shù)值,mul()可以定義為一個void函數(shù)。由此可以看出,可以利用全局變量減少函數(shù)實參與形參的個數(shù),從而減少內(nèi)存空間的占用以及傳遞數(shù)據(jù)時的時間消耗。此外,C語言規(guī)定外部變量、數(shù)組在定義時可以直接賦初值,而局部數(shù)組在定義時不能直接賦初值。按缺省的規(guī)定,如果外部變量沒有賦初值,則編譯程序就自動將它賦0初值。(2)建議不在必要時不要使用全局變量,因為:①全局變量在程序的全部執(zhí)行過程中都占用存儲單元,而不是僅在需要時才開辟單元。
5.3全局變量②它使函數(shù)在執(zhí)行時依賴于其所用的外部變量。如果將一個函數(shù)轉(zhuǎn)移到另一個文件中,還要將有關(guān)的外部變量及其值一起移過去。但若該外部變量與其他文件的變量同名時,就會出現(xiàn)問題,從而降低了程序的可靠性和通用性。在程序設(shè)計中,在劃分模塊時要求模塊的“內(nèi)聚性”強,與其他模塊的“耦合性”弱。即模塊的功能要單一(不要把許多互不相干的功能放在一個模塊中),與其他模塊的相互影響要盡量少。而用全局變量不合乎這個原則。一般要求把C程序中的函數(shù)做成一個封閉體,除了可以通過“實參-形參”的渠道與外界發(fā)生聯(lián)系外,沒有其他渠道。這樣的程序移植性好,可讀性強。③使用全局變量過多,會降低程序的清晰性,人們往往難以清楚地判斷出每個瞬時各個外部變量的值。在各個函數(shù)執(zhí)行時都可能改變外部變量的值,程序容易出錯。因此要限制使用全局變量。(3)如果外部變量在文件開頭定義,則在整個文件范圍內(nèi)都可以使用該外部變量;如果不在文件開頭定義,按上面規(guī)定,作用范圍只限于定義點到文件末尾。如果在定義點之前的函數(shù)想引用該外部變量,則應(yīng)該在該函數(shù)中用關(guān)鍵字extern作“外部變量說明”,表示該變量在函數(shù)外部定義,在函數(shù)內(nèi)部可以使用。
5.3全局變量【例5.5】引用外部變量的例子。intmax(x,y)/*定義max()函數(shù)*/intx,y;{intz;z=x>y?x:y;return(z);}main(){externinta,b;/*外部變量說明*/printf("%d",max(a,b));}inta=13,b=-8;/*外部變量在此定義*/運行結(jié)果如下:
135.3全局變量由于外部變量定義在主函數(shù)main()之后,因此在main()函數(shù)引用外部變量a和b之前,應(yīng)該用extern進(jìn)行外部變量說明。如果不作extern說明,編譯時將出錯。系統(tǒng)不會認(rèn)為a、b是已定義過的外部變量。一般做法是,把外部變量的定義放在引用它的所有函數(shù)之前,這樣可以避免在函數(shù)中加一個extern說明。需要強調(diào)的是,外部變量的定義和外部變量的說明不是一回事。外部變量的定義只能有一次,它的位置應(yīng)在所有函數(shù)之外,而同一個文件中外部變量的說明可以有多次,它的位置在函數(shù)之內(nèi)(哪個函數(shù)用在哪個函數(shù)中說明)。系統(tǒng)是根據(jù)外部變量的定義(而不是根據(jù)說明)來分配存儲單元。對外部變量的初始化只能在“定義”時進(jìn)行而不能在“說明”中進(jìn)行。所謂“說明”,其作用是申明該變量是已在外部定義過的變量,僅僅是為了引用該變量而作的“申明”。原則上,所有函數(shù)都應(yīng)對所用的外部變量作說明(用extern),只是為了簡化起見,在外部變量定義之后的函數(shù)可以省寫這個“說明”。(4)如果在同一源文件中,外部變量與局部變量同名,則在局部變量的作用范圍內(nèi),外部變量不起作用。
5.3全局變量【例5.6】局部變量與外部變量同名時,局部變量起作用的例程。這里故意重復(fù)使用a、b作變量名,是為了使讀者區(qū)別不同的a、b的含義和作用范圍。第一行定義了外部變量a、b,并使之初始化。第二行開始定義函數(shù)max,a、b是形參,形參也是局部變量。inta=3,b=5;/*a,b為外部變量*/max(a,b)inta,b;/*a,b為局部變量*/{intc;
c=a>b?a:b;
形參a,b的作用范圍
return(c);
外部變量a,b的作用范圍}(全程)main(){a=8;/*a為局部變量*/局部變量aprintf("%d",max(a,b));
的作用范圍
}運行結(jié)果為:85.3全局變量在函數(shù)max()中的a、b不是外部變量a、b,它們的值是由實參數(shù)傳遞而得到的,外部變量a、b在函數(shù)max()中不起作用。最后4行是main()函數(shù),它定義了一個局部變量a,因此全局變量a在main()函數(shù)范圍內(nèi)不起作用,而全局變量b在此范圍內(nèi)有效。所以printf()函數(shù)中的max(a,b)相當(dāng)于max(8,5),程序運行后得到結(jié)果為8。全局變量是在函數(shù)外部定義的,編譯時分配在靜態(tài)存儲區(qū),可以為程序中各個函數(shù)所引用。一個C程序可以由一個或多個源程序文件組成。全局變量在只有一個源文件組成的程序中的使用情況前邊已經(jīng)做了介紹,如果程序由多個源文件組成,某一個文件中的函數(shù)能否引用另一文件中的全局變量呢?答案是肯定的,方法也是在引用處用extern作說明。
5.3全局變量【例5.7】編寫程序,完成對給定a的值,輸入b和m,求a
b和am的值。文件file1.c中的內(nèi)容為:
inta;
main()
{intpower();
intb=3,c,d,m;
printf("Enterthenumberaanditspower:\n");
scanf("%d%d",&a,&m);
c=a
b;
printf("%d
%d=%d\n",a,b,c);
d=power(m);
printf("%d
%d=%d",a,m,d);
}文件file2.c中的內(nèi)容為:externinta;power(intn){5.3全局變量inti,y=1;
for(i=1;i<=n;i++)
y
=a;
return(y);}可以看到,file2.c文件中的開頭有一個extern說明(注意這個說明不是在函數(shù)內(nèi)部),它說明了本文件中出現(xiàn)的變量a是一個已經(jīng)在其他文件中定義過的變量,本文件不必為它分配內(nèi)存。本來外部變量的作用域如前述是從它的定義點到文件結(jié)束,但可以用extern說明將其作用域擴大到由extern說明的其他源文件。假如一個c程序有5個源文件,只在一個文件中定義了外部整形變量a,那么其他4個文件都可以引用變量a,但必須在每個文件中都加上一個“externinta;”說明。這樣,在各個文件經(jīng)過編譯后,將各目標(biāo)文件連接成一個可執(zhí)行的目標(biāo)文件。但是用這樣的全局變量時應(yīng)十分慎重,因為在執(zhí)行一個文件中的函數(shù)時,可能會改變該全局變量的值,這將會影響到另一個文件中的函數(shù)執(zhí)行結(jié)果。
5.3全局變量5.4寄存器變量為提高程序的執(zhí)行速度,在C語言中,允許將局部變量的值放在運算器的寄存器中,需要時直接從寄存器中取出參加運算,不必再到內(nèi)存中去取,這樣可以提高程序的執(zhí)行效率。這種變量叫“寄存器變量”,用關(guān)鍵字register作說明。例如:registerinti;registercharch;registerfloatx;等。在寄存器變量的說明中關(guān)鍵字int
可以省略?!纠?.8】輸出1到5每個數(shù)階乘的值。main(){inti;
for(i=1;i<=5;i++);
printf("%d!=%d\n",i,fac(i));}intfac(n)intn;{registerinti,f=1;
for(i=1;i<=n;i++)
f=f
i;
retern(f);}定義的局部變量f和i是寄存器變量,如果n的值大,則能節(jié)省許多執(zhí)行時間。這里強調(diào)幾點:l
只有局部自動變量和形式參數(shù)可以作為寄存器變量,其他(如全局變量)不行。在調(diào)用一個函數(shù)時占用一些寄存器來存放寄存器變量的值,函數(shù)調(diào)用結(jié)束則釋放所占用的寄存器。l
一個計算機系統(tǒng)中的寄存器數(shù)目是有限的,故不能定義任意多個寄存器變量。不同的計算機系統(tǒng)允許使用的寄存器數(shù)目有區(qū)別,如有的小型機只允許使用3個寄存器來容納寄存器變量。l
不同的系統(tǒng)對register變量的處理是不同的。TurboC對register變量當(dāng)作自動變量來處理,分配內(nèi)存單元,并不真正把它們放在寄存器中。因此雖然程序合法,但并不能提高執(zhí)行速度。5.4寄存器變量5.5靜態(tài)存儲變量靜態(tài)變量在說明時要加關(guān)鍵字static,如:{staticinti;
staticintj=1;
staticcharch='a';}它說明了i,j,ch三個靜態(tài)變量。
5.5.1局部靜態(tài)存儲變量如果一個靜態(tài)變量是在一個函數(shù)或語句塊內(nèi)說明的,那么該靜態(tài)變量是“局部的”,即其作用域被限制在該函數(shù)或塊內(nèi)。但是若希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,即其所占用的存儲單元不釋放,應(yīng)該指定該局部變量為“局部靜態(tài)變量”,用static加以說明。
【例5.10】打印1!到N!main(){intfactor();inti,n;printf("N=");scanf("%d",&n);for(i=1;i<=n;i++)
printf("%d!=%d\n",i,factor(i));}intfactor(p)intp;{staticf=1;f*=p;return(f);}5.5靜態(tài)存儲變量對局部靜態(tài)變量的說明:(1)局部靜態(tài)變量屬于靜態(tài)存儲類,在靜態(tài)存儲區(qū)內(nèi)分配存儲單元。在程序的整個運行期間都不釋放。(2)局部靜態(tài)變量是在編譯時賦初值的,即只賦初值一次,在程序運行時它已有初值。以后每次調(diào)用時不再賦初值而只是保留上次函數(shù)調(diào)用結(jié)束時的值。對自動變量的賦初值,不是在編譯時進(jìn)行而是在函數(shù)調(diào)用時進(jìn)行,每調(diào)用一次函數(shù)重新給一次初值,相當(dāng)于執(zhí)行一次賦值語句。(3)在定義局部靜態(tài)變量時不賦初值,編譯時自動賦0(對數(shù)值型變量)或空(對字符型變量)。(4)雖然局部靜態(tài)變量的值在函數(shù)調(diào)用結(jié)束后仍然存在,但其他函數(shù)是不能引用的。
5.5靜態(tài)存儲變量5.5.2全局靜態(tài)變量在程序設(shè)計中,有時希望某些全局變量只限于被本文件使用而不能被其他文件引用,這時可在定義外部變量時,前邊加一個static說明。file1.cfile2.cstaticinta;
externinta;main()fun(n){intn;
{
}a=a*n;
}5.5靜態(tài)存儲變量在file1.c中定義了一個全局變量a,但它有static說明,因此只能用于本文件。雖然file2.c文件中用了“externinta;”,但file2.c文件中無法使用file1.c文件中的全局變量a。這種加上static說明,只能用于本文件的外部變量(全局變量)稱為靜態(tài)外部變量,有些書上稱之為“函數(shù)外部靜態(tài)變量”。在程序設(shè)計中,常由若干人分別完成各個模塊,各人可以獨立地在設(shè)計的文件中使用相同的外部變量名而互不相干,這就為程序的模塊化、通用性提供了方便。一個文件與其他文件沒有數(shù)據(jù)聯(lián)系,可以根據(jù)需要任意地將所需的若干文件組合,而不必考慮文件間的變量是否同名和數(shù)據(jù)交叉。因此已知道其他文件不引用本文件說明的外部變量,可以對本文件中的外部變量都加上static,使之成為靜態(tài)外部變量,以免被其他文件誤用。需要指出,對外部變量加static說明,并不意味著這時才是靜態(tài)存儲而不加static說明的是動態(tài)存儲。兩種形式的外部變量都是靜態(tài)存儲,只是作用范圍不同而已。
5.5靜態(tài)存儲變量5.6動態(tài)存儲變量動態(tài)存儲方式是指在程序的運行過程中根據(jù)需要動態(tài)地分配存儲空間的方式。在動態(tài)存儲區(qū)中存放以下數(shù)據(jù):l
函數(shù)形參變量(只有在調(diào)用函數(shù)時才給形參分配存儲空間)。l
局部變量(加了static說明的除外)。l
函數(shù)調(diào)用時的現(xiàn)場保護(hù)和返回地址等。對以上這些數(shù)據(jù),在函數(shù)調(diào)用開始時才分配動態(tài)存儲空間,函數(shù)調(diào)用結(jié)束時則釋放這些臨時分配的空間。即程序執(zhí)行過程中這些分配和釋放是動態(tài)的,如果程序執(zhí)行過程中兩次調(diào)用同一函數(shù),分配給此函數(shù)中的局部變量的存儲空間地址可能是不同的。這里看一下局部變量的存儲方式。函數(shù)中的局部變量,如不做專門的說明(如說明為靜態(tài)的局部變量),都是動態(tài)分配存儲空間的,存儲在動態(tài)存儲區(qū)中。對它們分配和釋放存儲空間的工作是由編譯系統(tǒng)自動處理的,因此這類變量稱為自動變量。自動變量用關(guān)鍵字auto說明。例如:intf(a)/*定義函數(shù)*/inta;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 福建護(hù)坡加固施工方案
- 房屋買賣合同預(yù)售合同
- 中華傳統(tǒng)美文鑒賞教學(xué)方法:古詩解析與創(chuàng)作訓(xùn)練
- 屋面漏水導(dǎo)流施工方案
- 阜陽別墅木屋施工方案
- 接戶線施工方案
- 塔吊安裝專項施工方案
- 漢口閣樓安裝施工方案
- 鍋爐除渣干式排渣施工方案
- 年產(chǎn)12000噸聚羧酸高性能減水劑復(fù)配液及3000噸水泥助磨劑復(fù)配液項目環(huán)評報告表
- 2024年全國英語競賽《B類英語專業(yè)》初賽試題真題及答案
- 小學(xué)生中國舞課件大全
- 2025年南京信息職業(yè)技術(shù)學(xué)院單招職業(yè)技能測試題庫完整
- 《Spring框架》教學(xué)課件
- 2025年中考英語時文閱讀 6篇有關(guān)電影哪吒2和 DeepSeek的英語閱讀(含答案)
- 客戶溝通技巧與客戶投訴處理培訓(xùn)課件
- 完整版臨時用水用電施工方案
- 江蘇省南通市2025屆高三第一次調(diào)研測試數(shù)學(xué)試題(南通一模)(含答案)
- 【課件】進(jìn)出口貨物報關(guān)單填制
- Codesys培訓(xùn)課件教學(xué)課件
- 2024-2030年中國菊粉行業(yè)發(fā)展?fàn)顩r及競爭力研究報告
評論
0/150
提交評論