變量可以分爲:全局變 量、靜態全局變量、靜態局部變量和局部變量。
全局和靜態變量都在堆 裏。( 錯了,全局變量和靜態變量都在數據段,有些地方也叫靜態存儲區)
全局變量的作用範圍是整 個程序(如果程序是多個文件,必須在其他的文件中說明)。
靜態變量的作用範圍要看 靜態變量的位置,如果在函數裏,則作用範圍就是這個函數。
靜 態全局變量,只有本文件可以用。
全局變量是沒有定義存儲 類型的外部變量, 其作用域是從定義點到程序結束. 省 略了存儲類型符, 系統將默認爲是自動型.
靜態全局變量是定義存儲 類型爲靜態型的外部變量, 其作用域是從定義點到程序結束, 所 不同的是存儲類型決定了存儲地點, 靜態型變 量是存放在內存的數據區中的, 它們在程序開始運行前就分配了固定的字節, 在程序運行過程中被分配的字節大小是不改變的. 只有程 序運行結束後, 才釋放所佔用的內存.
自動型變量存放在堆棧區 中. 堆棧區也是內存中一部分, 該部分內存在 程序運行中是重複使用的.
按存儲區域分,全局變量、靜態全局變量和靜態局部變量都存放在內存的靜態存儲區域,局部變量存放在內存的棧區。
按作用域分,全局變量在整個工程文件內都有效;靜態全局變量只在定義它的文件內有效;靜態局部變量只在定義它的函數內有 效,只是程序僅分配一次內存,函數返回後,該變量不會消失;局部變量在定義它的函數內有效,但是函數返回後失效。
全 局變量和靜態變量如果沒有手工初始化,則由編譯器初始化爲0 。局部變量的值不可知。
int a; /*
全局*/
static int b; /*
靜態全局*/
int main()
{
}
這段代碼如果是寫在file.c
裏面的,那麼file2.c
就不能調用b;
但是file2.c
中可以通過聲明外部變
量extent a;
從而調用a
原帖及討論:http://bbs.bc-cn.net/dispbbs.asp?boardid=56&id=170039
*/
--------------------------------------------------------------------------------------
*/
出自: 編程中國 http://www.bc-cn.net
*/
作者: 中學者
*/
時間: 2007-9-14
編
程論壇首發
*/
聲明: 尊重作者勞動,轉載請保留本段文字
*/
--------------------------------------------------------------------------------------
變量和內存的問題,原來是自己理解,通過寫小代碼來驗證,但是總感覺有什麼地方不對,使我很混亂,所以
今天就在網上看了一些文章,然後重新認識了這個問題。下面算是我的認識,如果有不對的地方,請指出,多多交流................
我是新手!!!
C++
中內存的分配:
1.
棧:是用來存放像一般變量和函數參數等的一塊內存。系統會在變
量生存期結束時自動釋放內存,即把內存從棧中彈出。
2.
堆:用來存放動態變量,
如指針。要通過設計者自己管理變量,自行進行創建和清理工作。(利用new
和delete)
3.
自由存儲區:就是那些由malloc
等
分配的內存塊,他和堆是十分相似的,不過它是用free
來結束自己的生命的。
4.
全局/
靜態存儲區:全局變量和靜
態變量被分配到同一塊內存。
5.
常量存儲區:用來存儲常量,即不能被修改的變
量。
以上是內存分區的問題,下面是我理解的問題:
1.
變量聲明與定義:
聲明只是告訴編譯器有這麼一個變量,而定義在聲明的同時便進行內存分配。
//------1.cpp--------------
#include
using namespace std;
extern
int n;//
聲明變量n,
只告訴有這麼一個名字
void
function(int a){....};//
定義形參a,
並分配內存
int main(){
int i; //
定義變量i,
並分配內存
return 0;
}
其中,對於函數function, 形參a 的生存期在函數體內,在函數結束工作後,a 便被釋放,從棧中彈出 。(a 所佔的內存和內存地址 現在沒有變量使用了), 來看下面的代碼;
#include
using namespace std;
int
*p=NULL;
void fun(int a){ p=&a;}
int main(){
int
n=10;
fun(n);
cout<
return 0;
}
代碼執行的結果是顯示a
的內存地址,然而在原來的我理解是a
仍然佔着這塊內存區域,但是其實不是的,a
早已被彈
出棧,所以這塊區域是空着的。之所以會這樣,是因爲指針p
是全局的,p
存放了a
的地址,p
的生存期沒有結束,所以仍指向這塊地址,所以會顯示a
的
原來的內存地址。
由此,我就理解了傳值返回和引用返回,爲什麼引用返回不能返回局部變量。第一,引用返回返回的是實際地址,即可用的。第二,如果返回局部變量,那麼
局部變量結束生存期被釋放後,那塊內存就空着了,沒有變量用,所以不能操作
........
如
果用傳值返回返回局部變量卻是可行的,因爲傳值返回在執行renturn
語句的時候要進行拷貝,
把即將釋放的局部變量的值拷貝到臨時變量上。。
再來就是對於new
和delete:
//-----------------------------2.cpp--------
#include
using namespace std;
int
main(){
int *p=new int(4);//p
存儲在棧中,動態分配得到的內存存在堆中,從而通過指針指向一個無名字的堆來進行相關的操作.......
................
...........
delete
p;//
釋放p, p
還是指向原處,因爲p
沒
被釋放,被釋放的是無名字的堆內存區塊!!
return 0;
}
所
以,我就理解認爲,其實在編寫代碼時用到的變量,只不過是給底層的內存區域提供一個名字,然後間接地操作內存的內容...................
http://jpkc.cqit.edu.cn/jpkc/07/%E4%B8%8B%E8%BD%BD%E8%B5%84%E6%96%99/C%20%E8%AF%AD%E8%A8%80%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E9%9B%86/ccfaq.html