最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C語(yǔ)言之棧和堆(Stack && Heap)的優(yōu)缺點(diǎn)及其使用區(qū)別

 更新時(shí)間:2015年07月22日 09:16:45   作者:Scottzg  
本篇文章主要介紹了什么是棧(Stack) 、什么是堆( Heap),以及棧和堆的優(yōu)缺點(diǎn),同時(shí)介紹了應(yīng)該什么時(shí)候使用堆和棧,有需要的朋友可以參考下

一、前言

     直到現(xiàn)在,我們已經(jīng)知道了我們?nèi)绾温暶鞒A款?lèi)型,例如int,double,等等,還有復(fù)雜的例如數(shù)組和結(jié)構(gòu)體等。我們聲明他們有各種語(yǔ)言的語(yǔ)法,例如Matlab,Python等等。在C語(yǔ)言中,把這些變量放在棧內(nèi)存中。

二、基礎(chǔ)

     1、棧

          什么是棧,它是你的電腦內(nèi)存的一個(gè)特別區(qū)域,它用來(lái)存儲(chǔ)被每一個(gè)function(包括mian()方法)創(chuàng)建的臨時(shí)變量。棧是FILO,就是先進(jìn)后出原則的結(jié)構(gòu)體,它密切的被CPU管理和充分利用。每次function聲明一個(gè)新的變量,它就會(huì)被“推”到棧中。然后每次一個(gè)function退出時(shí),所有關(guān)于這個(gè)函數(shù)中定義的變量都會(huì)被釋放(換句話說(shuō)就是刪除)。一旦棧中的變量釋放,這塊區(qū)域就會(huì)變成可用的,提供給其他棧中的變量。

     用棧存儲(chǔ)變量的好處是,內(nèi)存是被你管理的。你不用手動(dòng)的創(chuàng)建內(nèi)存,不用當(dāng)你不在需要它的時(shí)候手動(dòng)釋放內(nèi)存。另外,由于CPU組織棧內(nèi)存很高效。讀出和寫(xiě)入棧變量是很快的。

     理解棧的關(guān)鍵是理解概念,當(dāng)一個(gè)function退出時(shí),所有它的變量都會(huì)從棧中彈出,以后都會(huì)永遠(yuǎn)消失。因此棧中的變量本質(zhì)是局部的。這和我們?cè)瓉?lái)理解為變量作用域或者本地或者全局變量是相關(guān)的。在C中,一個(gè)公共的bug 是從你程序中的一個(gè)function外嘗試訪問(wèn)一個(gè)在棧中的這個(gè)function的變量(在該function已經(jīng)退出后)。
    

關(guān)于棧的另一個(gè)特點(diǎn)我們應(yīng)該記住,就是存儲(chǔ)再棧中的變量的大小有限制。而堆上創(chuàng)建變量不用考慮。
    

總結(jié)棧:
      a、棧的生長(zhǎng)和伸縮就是函數(shù)壓入或者推出局部變量。
      b、我們不用自己去管理內(nèi)存,變量創(chuàng)建和釋放都是自動(dòng)的。
      c、棧中的變量只有在函數(shù)創(chuàng)建運(yùn)行時(shí)存在。
    

2、 堆
         

堆也是我們的計(jì)算機(jī)內(nèi)存中的一個(gè)區(qū)域,但是他不是自動(dòng)管理的。而且也不是被CPU密切的管理著。它是一片更加自由的內(nèi)存區(qū)域(很大)。要想在堆上創(chuàng)建內(nèi)存,我們必須使用malloc() 或者calloc(),他們都是C語(yǔ)言編譯的。一旦你在堆上分配內(nèi)存,當(dāng)你不在需要的時(shí)候你必須用free()去銷(xiāo)毀。如果你不銷(xiāo)毀或者銷(xiāo)毀失敗,你的程序就會(huì)有內(nèi)存泄露。換句話說(shuō)就是堆內(nèi)存會(huì)一直在,其他進(jìn)程無(wú)法使用。我們將會(huì)再調(diào)試部分看到,那里有一個(gè)叫做Valgrind的東西,它可以幫助你發(fā)現(xiàn)內(nèi)存泄露。
    

不像棧,堆沒(méi)有變量大小的限制(除了你電腦的物理限制條件外)。堆內(nèi)存讀出和寫(xiě)入都比較慢,因?yàn)樗仨毷褂弥羔槇D訪問(wèn)堆內(nèi)存。我們將會(huì)下面講解指針。
   

3、棧和堆的優(yōu)缺點(diǎn)
    

棧:
          a、快速訪問(wèn)。
          b、沒(méi)有必要明確的創(chuàng)建分類(lèi)變量,因?yàn)樗亲詣?dòng)管理的。
          c、空間被CPU高效地管理著,內(nèi)存不會(huì)變成碎片。
          d、只有局部變量
          e、受限于棧大小(取決于操作系統(tǒng))
          f、變量不能調(diào)整大小。
        堆:
          a、變量可以被全局訪問(wèn)
          b、沒(méi)有內(nèi)存大小限制
          c、(相對(duì))訪問(wèn)比較慢
          d、沒(méi)有高效地使用空間,隨著塊內(nèi)存的創(chuàng)建和銷(xiāo)毀,內(nèi)存可能會(huì)變成碎片。
          e、你必須管理內(nèi)存(變量的創(chuàng)建和銷(xiāo)毀你必須要負(fù)責(zé))
          f、變量大小可以用realloc( )調(diào)整
例如:    
          下面是一個(gè)在棧上創(chuàng)建變量的短程序。和我們看到的其他程序類(lèi)似

 #include <stdio.h>
 double multiplyByTwo (double input) {
 double twice = input * 2.0;
 return twice;
 }
 int main(int argc, const char * argv[]) {
 int age = 30;
 double salary = 12345.67;
 double myList[3] = {1.2,2.3,3.4};
 printf("double your salary is %.3f\n",multiplyByTwo(salary));
 return 0;
 }


  
 運(yùn)行結(jié)果如下: double your salary is 24691.340
    

在第7,8和9行,我們聲明了三個(gè)變量:一個(gè)int變量、一個(gè)double變量和一個(gè)包含三個(gè)包含double的數(shù)組。這三個(gè)變量在main()函數(shù)創(chuàng)建,被壓入棧中。當(dāng)main()函數(shù)退出(程序退出),這些變量就會(huì)出棧。同樣地,在multiplyByTwo函數(shù)中,第二個(gè)double變量,也會(huì)在multiplyByTwo()函數(shù)創(chuàng)建的時(shí)候壓入棧中。一旦函數(shù)退出,第二個(gè)變量就會(huì)出棧,永遠(yuǎn)地消失。
    

備注:有一種方法可以告訴C保持一個(gè)棧變量。即使它的創(chuàng)建函數(shù)退出。那就是用static關(guān)鍵字當(dāng)聲明變量的時(shí)候。一個(gè)變量用static關(guān)鍵之聲明,因此就會(huì)變成一個(gè)類(lèi)似與全局變量的東西。但是它僅僅在創(chuàng)建它的函數(shù)里面可見(jiàn)。這是一個(gè)奇怪的東西,除非你在一個(gè)非常特殊的情況下需要。
    

下面是另一個(gè)版本的創(chuàng)建變量在堆上而不是在棧上:

#include <stdio.h>
#include <stdlib.h>
 
double *multiplyByTwo (double *input) {
 double *twice = malloc(sizeof(double));
 *twice = *input *2.0;
 return twice;
}
int main(int argc, const char * argv[]) {
 int *age = malloc(sizeof(int));
 *age = 30;
 double *salary = malloc(sizeof(double));
 *salary = 12345.67;
 double *myList = malloc(3 * sizeof(double));
 myList[0] = 1.2;
 myList[1] = 3.4;
 myList[2] = 4.5;
 double *twiceSalary = multiplyByTwo(salary);
 
 printf("double your salary is %.3f\n",*twiceSalary);
 
 free(age);
 free(salary);
 free(myList);
 free(twiceSalary);
 
 return 0;
}

  
正如你所看到的,我們用malloc()去分配堆內(nèi)存,用free()去釋放它。這樣不是很大的處理,但是很笨重。還有一件要注意的事情是:這樣會(huì)由很多*號(hào)。這些是指針。malloc()(calloc()和free())函數(shù)處理的是指針而不是真正的數(shù)值。我們將會(huì)在下邊討論指針。指針在C棧是一個(gè)特殊的數(shù)據(jù)類(lèi)型,它用來(lái)存儲(chǔ)內(nèi)存的地址而不是存儲(chǔ)實(shí)際的values.因此在

*twice = *input *2.0;


  
這行,twice變量不是一個(gè)double,而是一個(gè)指向double的指針,是double被存儲(chǔ)再內(nèi)存中的地址。

4、什么時(shí)候使用堆
    

       我們應(yīng)該什么時(shí)候使用堆和棧呢?如果我們需要分配一大塊內(nèi)存(例如一個(gè)很大的數(shù)組或者一個(gè)很大的結(jié)構(gòu)體),而且我們需要保持這個(gè)變量很長(zhǎng)時(shí)間(例如全局變量)。我們應(yīng)該分配堆內(nèi)存。如果你處理的很小的變量,而且只要再函數(shù)使用的時(shí)候存活,那么你應(yīng)該使用棧,它比較方便而且快捷。如果你需要類(lèi)似與數(shù)組或者結(jié)構(gòu)體的變量,而且能夠動(dòng)態(tài)改變大?。ɡ缫粋€(gè)數(shù)組可以根據(jù)需要添加數(shù)據(jù)或者刪除數(shù)據(jù)),那么你可以用malloc(),realloc()給他們分配堆內(nèi)存,用free()手動(dòng)的管理內(nèi)存。當(dāng)我們討論完指針,我們將會(huì)討論動(dòng)態(tài)分配數(shù)據(jù)結(jié)構(gòu)體。

通過(guò)以上對(duì)棧和堆的介紹,希望對(duì)大家了解和區(qū)分棧和堆有所幫助。

相關(guān)文章

  • 淺談C/C++中的static與extern關(guān)鍵字的使用詳解

    淺談C/C++中的static與extern關(guān)鍵字的使用詳解

    本篇文章是對(duì)C/C++中的static與extern關(guān)鍵字的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語(yǔ)言中如何實(shí)現(xiàn)桶排序

    C語(yǔ)言中如何實(shí)現(xiàn)桶排序

    這篇文章主要介紹了C語(yǔ)言中如何實(shí)現(xiàn)桶排序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 詳解C++編程中多級(jí)派生時(shí)的構(gòu)造函數(shù)和訪問(wèn)屬性

    詳解C++編程中多級(jí)派生時(shí)的構(gòu)造函數(shù)和訪問(wèn)屬性

    這篇文章主要介紹了詳解C++編程中多級(jí)派生時(shí)的構(gòu)造函數(shù)和訪問(wèn)屬性,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • C++中單調(diào)棧的基本性質(zhì)介紹

    C++中單調(diào)棧的基本性質(zhì)介紹

    這篇文章主要介紹了單調(diào)棧的基本性質(zhì)介紹,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++實(shí)現(xiàn)自底向上的歸并排序算法

    C++實(shí)現(xiàn)自底向上的歸并排序算法

    這篇文章主要介紹了C++實(shí)現(xiàn)自底向上的歸并排序算法,結(jié)合實(shí)例形式較為詳細(xì)的分析總結(jié)了自底向上的歸并排序算法的原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-12-12
  • C++的缺省參數(shù)你了解嘛

    C++的缺省參數(shù)你了解嘛

    這篇文章主要為大家介紹了C++缺省參數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • 淺析C語(yǔ)言中assert的用法

    淺析C語(yǔ)言中assert的用法

    以下是對(duì)C語(yǔ)言中assert的使用方法進(jìn)行了介紹,需要的朋友可以參考下
    2013-07-07
  • Windows平臺(tái)下配置VS Code的C++環(huán)境教程

    Windows平臺(tái)下配置VS Code的C++環(huán)境教程

    這篇文章主要介紹了Windows平臺(tái)下配置VS Code的C++環(huán)境教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • C語(yǔ)言如何實(shí)現(xiàn)Unix時(shí)間戳與本地時(shí)間轉(zhuǎn)化

    C語(yǔ)言如何實(shí)現(xiàn)Unix時(shí)間戳與本地時(shí)間轉(zhuǎn)化

    這篇文章主要介紹了C語(yǔ)言如何實(shí)現(xiàn)Unix時(shí)間戳與本地時(shí)間轉(zhuǎn)化的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • 關(guān)于C++對(duì)象繼承中的內(nèi)存布局示例詳解

    關(guān)于C++對(duì)象繼承中的內(nèi)存布局示例詳解

    這篇文章主要給大家介紹了關(guān)于C++對(duì)象繼承中內(nèi)存布局的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08

最新評(píng)論

河源市| 色达县| 治县。| 淮南市| 思南县| 望城县| 封开县| 绵竹市| 株洲县| 湖口县| 安庆市| 高邮市| 营口市| 台北市| 乌恰县| 新疆| 锡林浩特市| 金阳县| 老河口市| 全南县| 偏关县| 富民县| 万州区| 双辽市| 安化县| 鹿泉市| 贵溪市| 宁晋县| 容城县| 嘉定区| 将乐县| 罗江县| 象山县| 灌阳县| 湖北省| 鄯善县| 宜川县| 武定县| 桃源县| 台州市| 宁武县|