C/C++ 的變量

變量可以分爲:全局變 量、靜態全局變量、靜態局部變量和局部變量。

全局和靜態變量都在堆 裏。( 錯了,全局變量和靜態變量都在數據段,有些地方也叫靜態存儲區)

全局變量的作用範圍是整 個程序(如果程序是多個文件,必須在其他的文件中說明)。

靜態變量的作用範圍要看 靜態變量的位置,如果在函數裏,則作用範圍就是這個函數。

靜 態全局變量,只有本文件可以用。

全局變量是沒有定義存儲 類型的外部變量, 其作用域是從定義點到程序結束. 省 略了存儲類型符, 系統將默認爲是自動型.

靜態全局變量是定義存儲 類型爲靜態型的外部變量, 其作用域是從定義點到程序結束, 所 不同的是存儲類型決定了存儲地點, 靜態型變 量是存放在內存的數據區中的, 它們在程序開始運行前就分配了固定的字節, 在程序運行過程中被分配的字節大小是不改變的. 只有程 序運行結束後, 才釋放所佔用的內存.

自動型變量存放在堆棧區 中. 堆棧區也是內存中一部分, 該部分內存在 程序運行中是重複使用的.

按存儲區域分,全局變量、靜態全局變量和靜態局部變量都存放在內存的靜態存儲區域,局部變量存放在內存的棧區。

按作用域分,全局變量在整個工程文件內都有效;靜態全局變量只在定義它的文件內有效;靜態局部變量只在定義它的函數內有 效,只是程序僅分配一次內存,函數返回後,該變量不會消失;局部變量在定義它的函數內有效,但是函數返回後失效。

全 局變量和靜態變量如果沒有手工初始化,則由編譯器初始化爲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.
堆:用來存放動態變量, 如指針。要通過設計者自己管理變量,自行進行創建和清理工作。(利用newdelete) 
    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 語句的時候要進行拷貝, 把即將釋放的局部變量的值拷貝到臨時變量上。。
­
    
再來就是對於newdelete:
//-----------------------------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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章