『壹』 程序的局部變數 全局變數 動態申請數據分別存儲在什麼地方
程序的局部變數 全局變數 動態申請數據分別存儲在什麼地方?
量的類別:
根據作用域可分為全局變數和局部變數。
根據生存周期可分為靜態存儲方式和動態存儲方式,具體地又分為自動的(auto)、靜態的(static)、寄存器的(register)、外部的(extern)。
靜態存儲方式是指在程序運行期間分配固定的存儲空間的方式,動態存儲方式是在程序運行期間根據需要進行動態的分配存儲空間的方式。
每一個變數均有作用域和存儲類別兩個屬性,這些屬性共同用於描述一個變數,這些不同類型的變數與存儲位置的關系如下:
外部變數(全局變數)、靜態外部變數、靜態局部變數存儲在靜態存儲區。
自動局部變數(局部變數默認為自動局部變數)、函數形參存儲在動態存儲區,不論是靜態存儲區還是動態存儲區均屬於內存中的用戶區。
但是,寄存器變數是存儲在CPU寄存器中的而不是內存中。
首先說明一下與作用域相關的幾個屬性:
局部變數:在一個函數內部定義的變數是內部變數,它只在本函數范圍內有效,也就是說只有在本函數內才能使用它們,在此函數以外是不能使用這些變數的,這種類型的變數就稱為「局部變數」。
全局變數:在函數外定義的變數,可以為本源文件中其它函數所公用,有效范圍為從定義變數的位置開始到本源文件結束,這種類型的變數就稱為「全局變數」。
接下來說明一下與存儲類型相關的幾個屬性:
atuo:在聲明局部變數時,若不指定 static,默認均是 auto,這類變數都是動態分配存儲空間的,數據存儲在動態存儲區中。
static:在聲明局部變數時,使用關鍵字 static 將局部變數指定為「靜態局部變數」,這樣在函數調用結束後不消失而保留原值,即佔用的存儲單元不釋放,在下一次函數調用時,該變數已有值就是上次函數調用結束時的值。
register:在聲明動態局部變數或者函數形參時,可將變數聲明為register,這樣編譯系統就會為變數分配一個寄存器而不是內存空間,通過這種方式可提升對某些局部變數頻繁調用的程序的性能。(寄存器運算速度遠高於內存)
extern:用於擴展全局變數的作用域,比如如果函數想引用一個外部變數,但該外部變數在該函數後定義,那麼這個函數需要使用 extern 來聲明變數,這樣才能使用在該函數後面定義的全局變數。此外,extern 還可以在多文件的程序中聲明外部變數。
由於變數從不同維度劃分,形成了多種錯綜復雜的關系,在學習編程的時候需要重點關注。
『貳』 編寫程序過程中要引用變數的存儲地址時,可以通過什麼來獲得
編寫程序過程中要引用變數的存儲地址時,以通過好腔局程序計數器PC來獲得。
名字編譯後會被映射成數據的地址(可以是絕對地址或者偏移地址),如何通過地址來訪問數據,本身就是代碼的一部分。而外部變數的地址,在編譯的時候還不能完全確定,就先空著,等鏈接的時候再進行回友讓填。
引用變數的存儲地址:
程序中用到的所有地址,都不是真實的內存地址,只是虛擬內存地址。程序用到虛擬內存,分成一頁頁,比如每頁是 4K。有些頁確實存儲在真實的內存當中,但圓坦有些頁存儲在磁碟當中,有些頁就單純空著。操作系統和硬體會將虛擬內存映射成真實的內存,具體的程序不用關心。
『叄』 51單片機定義變數時默認是存儲到哪裡的
未顯式聲明的情況下,變數會根據Memory Model的設置,默認分配在指定的存儲區。
Small模式:默認分配在data區
Compact模式:默認分配在pdata區
Large模式:默認分配在xdata區
新建工程默認都是Small模式,所以未顯式聲明存儲區域的變數都會分配在data區的。所以才會容易出現data區擠爆、編譯器跳著腳讓你把變數分到idata區去……
『肆』 局部變數 全局變數 動態變數分別存儲什麼位置
在C語言裡面,局部變數,全局變數都是存貯在棧(stack)裡面的,
而所有用malloc和new這種操作符動態分配的空間則都是存貯在堆(mp)裡面的,
舉個簡單的例子:
int *ptr;
ptr =(int*)malloc(100*sizeof(int));
這兩句中,ptr這個指針變數是存貯在棧裡面,但是他所指向的內容則是在堆裡面。明白了嗎
『伍』 程序的局部變數 全局變數 動態申請數據分別存儲在什麼地方
程序的局部變數全局變數動態申請數據分別存儲在棧里。
普通局部變數在堆棧空間上分配,當局部變數的函數被多次調用時,局部變數每次在堆棧上的位置都不相同。還可以在堆上動態分配局部變數(malloc),但是要記住在耗盡堆空間後釋放zd。
內存分配上的棧空間時要注意內存的,不能分配太多的內存。如果堆棧中的空間小於請求的空間大小,則系統將顯示堆棧溢出並給出相應的異常信息。但堆不同,堆可分配空間很大。
(5)鏈接腳本指定變數存儲位置擴展閱讀:
注意事項:
對局部變數進行分類
1.位置:編譯器將靜態局部變數放在全局存儲區域中。數據,因此盡管它是本地的,但它存在於程序的整個生命周期中(它在定義時產生,並隨著程序的結束而結束)。
2.訪問許可權:靜態局部變數只能由其作用域內的變數或函數訪問。也就是說,盡管它將存在於程序的整個生命周期中,但是其他函數和源文件不能訪問它,因為它是靜態的。
3.值:如果用戶沒有初始化靜態局部變數,編譯器會自動將其賦值為0,每次調用靜態局部變數時都會使用最後一次調用後的值。
『陸』 嵌入式系統為什麼自定義鏈接腳本
既然你說嵌入式系統,我就不多廢話了,直接說鏈接腳本,如果有不懂得歡迎提問,我大四和你一樣在學這方面內容。
如果我們不自己定義的話,編譯使用的是內部默認的鏈接腳本,鏈接腳本的本質就是說明程序的各個段(數據段,代碼段,bss段=》沒有被初始化的全局變數)保存在內存的什麼位置,這里涉及運行域和裝載域,我們把程序燒錄到flash中這時運行程序所在的地址稱之為裝載域(flash中的地址),由於程序中包含數據段和bss段他們是可以修改的,因此要把bss段數據段從裝載域(flash)拷貝到在ram中(稱之為運行域),當程序要訪問這個變數時,通過鏈接腳本定義的地址信息可以知道我們在內存的哪個地址訪問這個變數,本質就是指定運行域的地址,這就是鏈接腳本的本質,我們也可以把程序拷貝到內存中,在內存中運行,但是要靠鏈接腳本告訴我們程序(代碼段)在哪裡,變數在哪裡(數據段),好讓編譯器自動的給我們算好變數的地址信息,至於為什麼要自定義的話,根據要求板子打硬體環境定製的,例如我們的arm板子要跑linux,我們的程序燒錄到flash中,然後要拷貝到內存中,但是默認的鏈接腳本怎麼知道我們的各個段信保存在內存的哪裡?這時候需要我們自己定義鏈接腳本。