A13在c语言中是合法变量吗,C语言中局部变量和全局变量等在内存中的存放位置.doc-资源下载在线文库www.lddoc.cn...
C語言中局部變量和全局變量_等在內(nèi)存中的存放位置.doc
C 語言中局部變量和全局變量 變量的存儲類別static,extern,auto,register 8.8 局部變量和全局變量在討論函數(shù)的形參變量時曾經(jīng)提到,形參變量只在被調(diào)用期間才分配內(nèi)存單元,調(diào)用結(jié)束立即釋放。這一點表明形參變量只有在函數(shù)內(nèi)才是有效的,離開該函數(shù)就不能再使用了。這種變量有效性的范圍稱變量的作用域。不僅對于形參變量,語言中所有的量都有自己的作用域。變量說明的方式不同,其作用域也不同。語言中的變量,按作用域范圍可分為兩種,即局部變量和全局變量。8.8.1 局部變量局部變量也稱為內(nèi)部變量。局部變量是在函數(shù)內(nèi)作定義說明的。其作用域僅限于函數(shù)內(nèi),離開該函數(shù)后再使用這種變量是非法的。例如int f1int a /*函數(shù) f1*/int b,c; a,b,c 有效int f2int x /*函數(shù) f2*/int y,z; x,y,z 有效mainint m,n; m,n 有效在函數(shù) f1 內(nèi)定義了三個變量,a 為形參,b,c 為一般變量。在 f1 的范圍內(nèi) a,b,c 有效,或者說 a,b,c 變量的作用域限于 f1 內(nèi)。同理,x,y,z 的作用域限于 f2 內(nèi)。m,n 的作用域限于 main 函數(shù)內(nèi)。關(guān)于局部變量的作用域還要說明以下幾點1 主函數(shù)中定義的變量也只能在主函數(shù)中使用,不能在其它函數(shù)中使用。同時,主函數(shù)中也不能使用其它函數(shù)中定義的變量。因為主函數(shù)也是一個函數(shù),它與其它函數(shù)是平行關(guān)系。這一點是與其它語言不同的,應(yīng)予以注意。2 形參變量是屬于被調(diào)函數(shù)的局部變量,實參變量是屬于主調(diào)函數(shù)的局部變量。3 允許在不同的函數(shù)中使用相同的變量名,它們代表不同的對象,分配不同的單元,互不干擾,也不會發(fā)生混淆。如在前例中,形參和實參的變量名都為 n,是完全允許的。4 在復合語句中也可定義變量,其作用域只在復合語句范圍內(nèi)。例如mainint s,a;int b;sab; /*b 作用域*/ /*s,a 作用域*/【例 8.12】mainint i2,j3,k;kij;int k8;printf“dn“,k;printf“dn“,k;本程序在 main 中定義了 i,j,k 三個變量,其中 k 未賦初值。而在復合語句內(nèi)又定義了一個變量 k,并賦初值為 8。應(yīng)該注意這兩個 k 不是同一個變量。在復合語句外由 main 定義的 k 起作用,而在復合語句內(nèi)則由在復合語句內(nèi)定義的 k 起作用。因此程序第 4 行的 k為 main 所定義,其值應(yīng)為 5。第 7 行輸出 k 值,該行在復合語句內(nèi),由復合語句內(nèi)定義的k 起作用,其初值為 8,故輸出值為 8,第 9 行輸出 i,k 值。i 是在整個程序中有效的,第7 行對 i 賦值為 3,故以輸出也為 3。而第 9 行已在復合語句之外,輸出的 k 應(yīng)為 main 所定義的 k,此 k 值由第 4 行已獲得為 5,故輸出也為 5。8.8.2 全局變量全局變量也稱為外部變量,它是在函數(shù)外部定義的變量。它不屬于哪一個函數(shù),它屬于一個源程序文件。其作用域是整個源程序。在函數(shù)中使用全局變量,一般應(yīng)作全局變量說明。只有在函數(shù)內(nèi)經(jīng)過說明的全局變量才能使用。全局變量的說明符為 extern。但在一個函數(shù)之前定義的全局變量,在該函數(shù)內(nèi)使用可不再加以說明。例如int a,b; /*外部變量*/void f1 /*函數(shù) f1*/float x,y; /*外部變量*/int fz /*函數(shù) fz*/main /*主函數(shù)*/從上例可以看出 a、b 、x、y 都是在函數(shù)外部定義的外部變量,都是全局變量。但 x,y 定義在函數(shù) f1 之后,而在 f1 內(nèi)又無對 x,y 的說明,所以它們在 f1 內(nèi)無效。a,b 定義在源程序最前面,因此在 f1,f2 及 main 內(nèi)不加說明也可使用。【例 8.13】輸入正方體的長寬高 l,w,h。求體積及三個面 x*y,x*z,y*z 的面積。int s1,s2,s3;int vs int a,int b,int cint v;va*b*c;s1a*b;s2b*c;s3a*c;return v;mainint v,l,w,h;printf“n length,width and heightn“;scanf“ddd“,vvsl,w,h;printf“nvd,s1d,s2d,s3dn“,v,s1,s2,s3;【例 8.14】外部變量與局部變量同名。int a3,b5; /*a,b 為外部變量*/maxint a,int b /*a,b 為外部變量*/int c;cabab;returnc;mainint a8;printf“dn“,maxa,b;如果同一個源文件中,外部變量與局部變量同名,則在局部變量的作用范圍內(nèi),外部變量被“ 屏蔽” ,即它不起作用。8.9 變量的存儲類別8.9.1 動態(tài)存儲方式與靜態(tài)動態(tài)存儲方式前面已經(jīng)介紹了,從變量的作用域(即從空間)角度來分,可以分為全局變量和局部變量。從另一個角度,從變量值存在的作時間(即生存期)角度來分,可以分為靜態(tài)存儲方式和動態(tài)存儲方式。靜態(tài)存儲方式是指在程序運行期間分配固定的存儲空間的方式。動態(tài)存儲方式是在程序運行期間根據(jù)需要進行動態(tài)的分配存儲空間的方式。用戶存儲空間可以分為三個部分1 程序區(qū);2 靜態(tài)存儲區(qū);3 動態(tài)存儲區(qū);全局變量全部存放在靜態(tài)存儲區(qū),在程序開始執(zhí)行時給全局變量分配存儲區(qū),程序行完畢就釋放。在程序執(zhí)行過程中它們占據(jù)固定的存儲單元,而不動態(tài)地進行分配和釋放;動態(tài)存儲區(qū)存放以下數(shù)據(jù)1 函數(shù)形式參數(shù);2 自動變量(未加 static 聲明的局部變量);3 函數(shù)調(diào)用實的現(xiàn)場保護和返回地址;對以上這些數(shù)據(jù),在函數(shù)開始調(diào)用時分配動態(tài)存儲空間,函數(shù)結(jié)束時釋放這些空間。在 c 語言中,每個變量和函數(shù)有兩個屬性數(shù)據(jù)類型和數(shù)據(jù)的存儲類別。8.9.2 auto 變量函數(shù)中的局部變量,如不專門聲明為 static 存儲類別,都是動態(tài)地分配存儲空間的,數(shù)據(jù)存儲在動態(tài)存儲區(qū)中。函數(shù)中的形參和在函數(shù)中定義的變量(包括在復合語句中定義的變量),都屬此類,在調(diào)用該函數(shù)時系統(tǒng)會給它們分配存儲空間,在函數(shù)調(diào)用結(jié)束時就自動釋放這些存儲空間。這類局部變量稱為自動變量。自動變量用關(guān)鍵字 auto 作存儲類別的聲明。例如int fint a /*定義 f 函數(shù),a 為參數(shù)*/auto int b,c3; /*定義 b,c 自動變量*/a 是形參,b,c 是自動變量,對 c 賦初值 3。執(zhí)行完 f 函數(shù)后,自動釋放a,b,c 所占的存儲單元。關(guān)鍵字 auto 可以省略,auto 不寫則隱含定為“自動存儲類別”,屬于動態(tài)存儲方式。8.9.3 用 static 聲明局部變量有時希望函數(shù)中的局部變量的值在函數(shù)調(diào)用結(jié)束后不消失而保留原值,這時就應(yīng)該指定局部變量為“靜態(tài)局部變量”,用關(guān)鍵字 static 進行聲明。【例 8.15】考察靜態(tài)局部變量的值。fint aauto b0;static c3;bb1;cc1;returnabc;mainint a2,i;fori0;iyxy;returnz;mainextern A,B;printf“dn“,maxA,B;int A13,B-8;說明在本程序文件的最后 1 行定義了外部變量 A,B,但由于外部變量定義的位置在函數(shù) main 之后,因此本來在 main 函數(shù)中不能引用外部變量 A,B。現(xiàn)在我們在 main 函數(shù)中用 extern 對 A 和 B 進行“外部變量聲明”,就可以從“聲明”處起,合法地使用該外部變量 A 和 B。對于 malloc 而來的變量存儲在堆(heap)中,局部變量都存儲在棧(stack)中。堆和棧的區(qū)別堆和棧的區(qū)別 一個由 c/C編譯的程序占用的內(nèi)存分為以下幾個部分 1、棧區(qū)(stack) 由編譯器自動分配釋放,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。 2、堆區(qū)( heap) 一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時可能由 OS 回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,呵呵。 3、全局區(qū)(靜態(tài)區(qū))(static),全局變量和靜態(tài)變量的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。 - 程序結(jié)束后有系統(tǒng)釋放 4、文字常量區(qū) 常量字符串就是放在這里的。 程序結(jié)束后由系統(tǒng)釋放 5、程序代碼區(qū)存放函數(shù)體的二進制代碼。在全局變量和全局靜態(tài)變量有什么區(qū)別在全局變量和全局靜態(tài)變量有什么區(qū)別變量可以分為全局變量、靜態(tài)全局變量、靜態(tài)局部變量和局部變量。 按存儲區(qū)域分,全局變量、靜態(tài)全局變量和靜態(tài)局部變量都存放在內(nèi)存的靜態(tài)存儲區(qū)域,局部變量存放在內(nèi)存的棧區(qū)。 按作用域分,全局變量在整個工程文件內(nèi)都有效;靜態(tài)全局變量只在定義它的文件內(nèi)有效;靜態(tài)局部變量只在定義它的函數(shù)內(nèi)有效,只是程序僅分配一次內(nèi)存,函數(shù)返回后,該變量不會消失;局部變量在定義它的函數(shù)內(nèi)有效,但是函數(shù)返回后失效。 全局變量和靜態(tài)變量如果沒有手工初始化,則由編譯器初始化為 0。局部變量的值不可知。 靜態(tài)全局變量,只本文件可以用。 全局變量是沒有定義存儲類型的外部變量,其作用域是從定義點到程序結(jié)束.省略了存儲類型符,系統(tǒng)將默認為是自動型. 靜態(tài)全局變量是定義存儲類型為靜態(tài)型的外部變量,其作用域是從定義點到程序結(jié)束,所不同的是存儲類型決定了存儲地點,靜態(tài)型變量是存放在內(nèi)存的數(shù)據(jù)區(qū)中的,它們在程序開始運行前就分配了固定的字節(jié),在程序運行過程中被分配的字節(jié)大小是不改變的.只有程序運行結(jié)束后,才釋放所占用的內(nèi)存. 自動型變量存放在堆棧區(qū)中.堆棧區(qū)也是內(nèi)存中一部分,該部分內(nèi)存在程序運行中是重復使用的.聲明變量與定義變量有什么區(qū)別聲明是向編譯器介紹名字標識符。它告訴編譯器“這個函數(shù)或變量在某處可找到,它的模樣象什么”。而定義是說“在這里建立變量”或“在這里建立函數(shù)”。它為名字分配存儲空間。無論定義的是函數(shù)還是變量,編譯器都要為它們在定義點分配存儲空間。對于變量,編譯器確定變量的大小,然后在內(nèi)存中開辟空間來保存其數(shù)據(jù),對于函數(shù),編譯器會生成代碼,這些代碼最終也要占用一定的內(nèi)存。 在 C 和 C中,可以在不同的地方聲明相同的變量和函數(shù),但只能有一個定義(有時這稱為ODR,單一定義規(guī)則)。 定義也可以是聲明,如果有 int x;,之前編譯器未發(fā)現(xiàn)標識符 x,編譯器則把這一標識符看成是定義并立即為它分配存儲空間。 。 對“變量聲明”的解釋向來模糊且自相矛盾。 函數(shù)聲明包括函數(shù)類型、函數(shù)名、參數(shù)列表和一個分號,這些信息足以編譯器認出它是一個函數(shù)聲明并可識別出這個函數(shù)的外部特征。由此推斷,變量聲明應(yīng)是類型標識后面跟一個標識符。如 int a;但這產(chǎn)生了一個矛盾,這段代碼有足夠的信息讓編譯器為之分配存儲空間,而且編譯器也確實給之分配了存儲空間。要解決這個問題,對于 C 和 C需要一個關(guān)鍵字來說明“這是一個聲明,它的定義在別的地方”,這個關(guān)鍵字就是 extern,它表示變量是在文件以外定義的,或在文件后面定義的。 在變量定義前加 extern 表示聲明一個變量但不定義它,如 extern int a; extern 也可用于函數(shù)聲明,如 extern int func1int length,int width; 但由于沒有函數(shù)體,編譯器必把它當成聲明而非定義,extern 對于函數(shù)來說是多余的、可選的。C 語言的設(shè)計者并不要求函數(shù)聲明使用 extern,這可能有些令人遺憾,如果函數(shù)聲明也要求用 extern,那么形式上與變量聲明更加一致了,從而減少了混亂(但這就需要更多的輸入,這也許能解釋為什么不要求函數(shù)聲明使用 extern 的原因)。 什么是字節(jié)對齊,為什么要對齊 現(xiàn)代計算機中內(nèi)存空間都是按照 byte 劃分的,從理論上講似乎對任何類型的變量的訪問可以從任何地址開始,但實際情況是在訪問特定類型變量的時候經(jīng)常在特定的內(nèi)存地址訪問,這就需要各種類型數(shù)據(jù)按照一定的規(guī)則在空間上排列,而不是順序的一個接一個的排放,這就是對齊。 對齊的作用和原因各個硬件平臺對存儲空間的處理上有很大的不同。一些平臺對某些特定類型的數(shù)據(jù)只能從某些特定地址開始存取。比如有些架構(gòu)的CPU 在訪問一個沒有進行對齊的變量的時候會發(fā)生錯誤,那么在這種架構(gòu)下編程必須保證字節(jié)對齊.其他平臺可能沒有這種情況,但是最常見的是如果不按照適合其平臺要求對 數(shù)據(jù)存放進行對齊,會在存取效率上帶來損失。比如有些平臺每次讀都是從偶地址開始,如果一個 int 型(假設(shè)為 32 位系統(tǒng))如果存放在偶地址開始的地方,那么一個讀周期就可以讀出這 32bit,而如果存放在奇地址開始的地方,就需要 2 個讀周期,并對兩次讀出的結(jié)果的高低字節(jié)進行拼湊才能得到該 32bit 數(shù) 據(jù)。顯然在讀取效率上下降很多。 在 C 語言里面,局部變量,全局變量都是存貯在棧( stack)里面的,而所有用 malloc 和 new 這種操作符動態(tài)分配的空間則都是存貯在堆(dump)里面的,舉個簡單的例子int *ptr;ptr int*malloc100*sizeofint;這兩句中,ptr 這個指針變量是存貯在棧里面,但是他所指向的內(nèi)容則是在堆里面。
總結(jié)
以上是生活随笔為你收集整理的A13在c语言中是合法变量吗,C语言中局部变量和全局变量等在内存中的存放位置.doc-资源下载在线文库www.lddoc.cn...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c语言放空一个数组,C++语言
- 下一篇: android中的常用方法,androi