【问题标题】:What does LIFO really mean?LIFO 的真正含义是什么?
【发布时间】:2011-12-08 03:20:24
【问题描述】:

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

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

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

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

例子:

int main() {
 int a;
 int b;

 b = 5;
 a = 6;
}

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

我是不是误会了什么?这是什么?

【问题讨论】:

    标签: c++ stack computer-science


    【解决方案1】:

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

    一个堆栈是为您的应用程序分配一些内存的地方。这将是关于堆栈和堆以及内存分配位置的讨论的一部分。

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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

        我是不是误会了什么?这是什么?

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

        【讨论】:

          【解决方案4】:

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

          每个进程基本上由地址空间的 4 部分组成,它们分别是 进程可访问 当它运行时

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

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

          1) 初始化只读数据 - 这包含数据元素 由程序初始化,并且它们在运行期间只读 进程的执行。

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

          3)未初始化的数据 - 这包含的元素不是 由程序初始化并在进程执行前设置为 0。 这些也可以修改并称为 BSS(块开始符号)。这 这些元素的建议是,系统不必在 该区域的程序文件,b'因为它在操作系统之前被初始化为 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 个(主要?)段/部分。 text - 程序文本(显然是 const char 数组。可能还有其他 'const' 数组,因为无论如何都无法更改)。我不是 100% 确定数组部分,也许 有人会纠正我。

          data - 初始化的全局数据。见下面的例子。 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 段中的对象只有名称和大小,没有值。

          【讨论】:

            【解决方案5】:

            您不必按定义的顺序使用它们。但它们被销毁 - 从堆栈中移除 - 按此顺序。 LIFO 不是指访问,只是把东西放在堆栈上或从堆栈中取出。

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

            【讨论】:

              【解决方案6】:

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

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

              【讨论】:

                【解决方案7】:

                堆栈程序:

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

                堆栈内存:

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

                【讨论】:

                  猜你喜欢
                  • 2017-05-06
                  • 2012-03-30
                  • 2011-10-10
                  • 2012-08-03
                  • 2012-01-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-02-02
                  相关资源
                  最近更新 更多