LIFO究竟意味着什么?

时间:2011-12-08 03:20:25

标签: c++ stack computer-science

如本教程中所述: http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/

  

在计算机编程中,堆栈是容纳其他容器的容器   变量(很像一个数组)。但是,阵列可以让你   按您希望的任何顺序访问和修改元素,堆栈更多   有限。可以在堆栈上执行的操作是相同的   对于上面的那些:

     

1)查看堆栈顶部的项目(通常通过函数完成)   名为top())2)将顶部项目从堆栈中取出(通过a。完成   函数叫pop())3)在堆栈顶部放一个新项目(通过   一个叫做push()的函数

但如果我在C ++中定义了两个变量,我就不必按照相同的定义顺序使用它们了:

示例:

int main() {
 int a;
 int b;

 b = 5;
 a = 6;
}

这段代码有问题吗?我可以按照我喜欢的任何顺序使用它们!我不必首先使用 a ,然后使用 b

我误解了什么吗?它是什么?

7 个答案:

答案 0 :(得分:8)

你混淆了两种不同的堆栈。

一个堆栈,用于分配应用程序的某些内存。这将是关于堆栈和堆以及分配内存的讨论的一部分。

另一种堆栈是符合LIFO访问方式的数据结构。这可以使用std :: vector或其他形式的数据结构来实现。

答案 1 :(得分:4)

是的,保存被调用方法的局部变量的“自动存储”在堆栈中分配。但是使用自动存储堆栈,您可以推送和弹出(可变大小)“堆栈帧”,其中包含方法的所有局部变量,而不是单个值。

这在概念上类似于您引用的文章中讨论的堆栈类型,只是推送和弹出的项目要大得多。

在这两种情况下,机制都是“LIFO”,因为当你调用一个方法时你实际上是通过“弹出堆栈”返回 - 你总是必须以你调用它们的相反顺序从方法返回。

答案 2 :(得分:1)

  

我误解了什么吗?它是什么?

你把'a'和'b'打开的“堆栈”是(警告巨大的简化和概念)不是由变量构成的;它是由堆栈框架组成的。堆栈帧由函数的参数和返回值的空间组成,有时还包括函数中使用的变量(除了这些变量也可以保存在寄存器中,有时参数也通过寄存器传递)。通过调用函数来“推送”到该堆栈上。从该堆栈“弹出”是通过从函数返回来完成的。你确实只能访问“top”元素;你不能只读取调用当前函数的函数的变量,除非它们作为参数显式传入。

答案 3 :(得分:1)

与任何其他数据结构一样,堆栈是遵循LIFO(后进先出)原则的数据结构。如您的问题所述,它根据LIFO原则进行推送和弹出操作以输入和检索数据。

每个进程基本上由4个地址空间部分组成 可以访问该过程 何时运行

文本 - 此部分包含实际的m / c指令 执行。在许多操作系统上,这被设置为只读,因此 进程无法修改其说明。这允许多个实例 分享文本单一副本的程序。

数据 - 此部分包含程序的数据部分。它更进一步 分为

1)初始化只读数据 - 包含数据元素 由程序初始化,它们只在读取期间读取 执行过程。

2)初始化读写数据 - 包含数据元素 由程序初始化并将在过程中修改 流程执行。

3)未经初始化的数据 - 这包含的元素不是 由程序初始化并在进程执行前设置为0。 这些也可以修改并称为BSS(块起始符号)。该 adv这样的元素是,系统不必分配空间 该区域的程序文件,b'coz在OS之前被OS初始化为0 过程开始执行。

Stack - 此部分用于局部变量,堆栈帧

堆 - 此部分包含动态分配的内存

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个(主要?)段/部分。 text - 程序文本(显然是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段中的对象只有名称和大小,但没有值。

答案 4 :(得分:1)

您不必按照定义的顺序使用它们。但是它们被销毁 - 按顺序从堆栈中取出。 LIFO并不是指访问,只是将内容放在堆栈上或从堆栈中取出。

您可以通过更改int来打印在其析构函数中的类型来轻松地观察到这一点。

答案 5 :(得分:0)

堆栈是一种在整个地方使用的标准数据结构。线程所谓的堆栈实际上是这种范例的实现。有一个堆栈指针(通常在处理器寄存器中)指向一个内存位置。通过移动sp将数据“推”到该堆栈上。我们通过返回它指向的值并将sp向相反方向移动来“弹出”。

就你的a,b声明,它没有任何区别。它们在被使用之前都被分配了。

答案 6 :(得分:0)

堆叠程序:

您的示例程序不是堆栈的实现。堆栈应存储元素,如数组(或通过某种方式),其中元素可以按LIFO(后进先出)顺序推送(存储)或加载(拉出)。它的实现并不像声明两个变量那么简单。标准C ++提供了堆栈类,因此您可以使用它而无需自己实现。

堆叠内存:

函数中的变量以LIFO顺序存储在堆栈存储器(RAM中的某处)中。从您的示例中,将创建Variable a并将其推送到堆栈内存。然后,变量b被推送到堆栈存储器。函数完成执行后,变量以LIFO方式销毁。所以变量b是第一个被破坏的,最后变量a被破坏了。你没有为它编写代码。编译器会为它编写汇编低级代码。