2011-12-08 96 views
0

如本教程提到: http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/LIFO的真正含義是什麼?

在計算機編程,堆棧是保持其他變量 (很像數組)的容器。但是,儘管數組允許您以任何順序訪問和修改元素,但堆棧更受限於 。可以在堆棧上執行的操作是相同的 上述的那些:

1)看堆棧上的最上面的項目(通常是通過一函數 所謂的頂部完成的())2)取頂部項關堆棧(通過 函數調用pop()完成)3)把堆棧(通過 所完成的功能稱爲推())

之上的新的項目,但如果我定義在C上兩個變量++我不必按照相同的順序使用它們:

例如:

int main() { 
int a; 
int b; 

b = 5; 
a = 6; 
} 

這段代碼有問題嗎?我可以按我喜歡的任何順序使用它們!我不必先使用a然後再使用b

我誤會了什麼嗎?它是什麼?

回答

8

你混淆了兩種不同的堆棧。

一個堆棧,是您的應用程序的一些內存分配的地方。這將是關於堆棧和堆以及內存分配的討論的一部分。

另一種堆棧是符合LIFO訪問方式的數據結構。這可以使用std :: vector或其他形式的數據結構來實現。

+2

或'std :: stack'本身。 – GManNickG

0

堆棧是一個遍佈各地的標準數據結構。線程的所謂堆棧實際上是這種範式的實現。有一個指向內存位置的堆棧指針(通常位於處理器寄存器中)。通過移動sp將數據「推送」到這個堆棧上。我們通過返回它指向的值並彈出相反的方向來「彈出」。

只要你的a,b聲明在上面沒有區別。它們在使用前都進行了分配。

4

是的,保存被調用方法的局部變量的「自動存儲」被分配在一個堆棧中。但是對於自動存儲堆棧,可以推送和彈出(可變大小)的「堆棧幀」,其中包含方法的所有局部變量,而不是單個值。

這與概念上類似於您引用的文章中討論的堆棧類型,除了被推入和彈出的項目要大得多。

在這兩種情況下,機制都是「LIFO」,因爲當你調用一個方法時,你基本上是通過「彈出堆棧」來返回 - 你總是必須按照你調用它們的相反順序返回方法。

1

我誤解了什麼嗎?它是什麼?

你把'a'和'b'放在「堆棧」上(WARNING HUGE SIMPLIFICATIONS AND CONCEPTIZATIONIZATIONS AHEAD)不是由變量構成的;它是由堆棧框架構成的。一個堆棧幀包含函數的參數和返回值的空間,有時也包含函數中使用的變量(除了這些變量也可以保存在寄存器中,有時還通過寄存器傳遞參數)。通過調用一個函數來完成「推入」這個堆棧。從該堆棧中「彈出」是通過從函數返回來完成的。你確實只能訪問「頂部」元素;你不能只讀取調用當前函數的函數的變量,除非它們被顯式作爲參數傳入。

0

棧的程序:

你的示例程序不是棧的實現。堆棧應存儲元素,如數組(或通過某種方式),其中元素可按LIFO(後進先出)順序推送(存儲)或放入(拉出)。它的實現並不像聲明兩個變量那麼簡單。標準C++提供了堆棧類,以便您可以使用它,而無需自行實施。

堆棧存儲器中:

在變量的函數被存儲在堆棧存儲器(某處在RAM)LIFO順序。在你的例子中,變量a將被創建並推送到堆棧內存。然後,變量b被壓入堆棧內存。在函數完成它的執行後,變量將以LIFO方式銷燬。所以變量b是第一個被銷燬,最後變​​量a被銷燬。你不寫它的代碼。編譯器負責爲它編寫彙編低級代碼。

1

像其他任何數據結構一樣,堆棧是遵循LIFO(後進先出)原則的數據結構。正如您的問題所述,它根據LIFO原理執行用於輸入和檢索數據的推送和彈出操作。

每個進程包括地址空間基本上4部分是 訪問的過程 當它正在運行

文本的 - 該部分包含實際M/C指令是 執行。在許多操作系統上,它被設置爲只讀,所以 進程不能修改其指令。這允許程序的多個實例共享文本的單個副本。

數據 - 該部分包含程序的數據部分。它furthere 分爲

1)初始化只讀數據 - 這包含的數據元素 由程序初始化,並且它們是在執行 過程期間只讀。

2)初始化讀寫數據 - 包含數據元素 ,這些數據元素由程序初始化,並將在 過程執行過程中進行修改。

3)未完成的數據 - 這包含的元素不是 由程序初始化並且在進程執行之前設置爲0。 這些也可以修改和引用爲BSS(塊啓動符號)。此類元素的 是,系統不必在該區域的 程序文件中分配空間,b'coz在 進程開始執行之前將其初始化爲0。

堆棧 - 該部分被用於局部變量,堆棧幀

堆 - 該部分包含所述動態分配的內存

int abc = 1;       ----> Initialized Read-Write Data 
char *str;        ----> BSS 
const int i = 10;      -----> Initialized Read-Only Data 

main() 
{ 
    int ii,a=1,b=2,c;       -----> Local Variables on 
Stack 

    char *ptr; 
    ptr = malloc(4);      ------> Allocated Memory in Heap 

    c= a+b;        ------> Text 

} 

數據,存儲數據 文本,商店代碼

有是由鏈接器生成的3(主要?)段/文件段。 文本 - 程序文本(顯然是const char數組,也許是其他'const'數組,因爲無論如何都不能改變它們)。我不是100%確定陣列部分,也許 有人會糾正我。數據 - 初始化全局數據。見下面的例子。 bss - 未初始化的全局數據。 下面是一些例子

int x = 1; /* goes into data */ 
int y;  /* goes into bss */ 
const int z = 1; 

這一點,我們已經看到了進入「文」,既然不能改變反正,但可以保護

const char array[] = {'a','b'....etc} 


/* the rest goes into text */ 

int main(void) 
    { 
    return EXIT_SUCCESS; 
    } 

塊發起者符號

(BSS)由Unix連接器產生的未初始化的數據段。其他段是包含程序代碼的「文本」段,「數據」段包含初始化數據。 bss段中的對象只有名稱和大小,但沒有值。

1

您不必使用他們在定義的順序。但他們是銷燬 - 從堆棧中取出 - 按順序。 LIFO不會提及訪問權限,只會將其放置在堆棧上或將其從堆棧中取出。

通過更改int可以輕鬆地觀察到在打印析構函數中打印的類型。

相關問題