C++中的调用栈是先进先出吗?

5
每次调用函数时,激活记录的堆栈(通常只称为堆栈)会新增一条记录。相反地,当函数返回时,它的记录不再使用,因此依此类推。 堆栈(也称为调用堆栈)是一种数据结构,其按照“先进先出”的规则从一端增长和缩小。最后一行是否正确?我在《C++程序设计语言》一书中读到了这句话。

请问您所说的“the statement is like”是什么意思?这不是一个正确构成的句子。 - paddy
为什么你要质疑最后一行?我的意思不是让你盲目接受所读的内容,但随意选择信任或者不信任某些特定的行看起来很奇怪。是什么导致你选择了这行?有什么具体的地方让你感到不合理吗? - JaMiT
4
我在网上找到了一份文本副本:你确实从第8.5节倒数第二段中引用得正确。勘误表中没有相关条目。我不太清楚,但栈肯定是先进后出和后进先出,而不是先进先出。Stroustrup 在他的术语表 这里 中说道:"stack - (1) 内存用于保存函数的局部变量。(2) 标准库的先进后出序列。TC++PL 10.4.3、17.3.1,D&E 2.3、3.9." - Tony Delroy
1
先进先出意味着您调用的第一个函数(通常是C++中的main函数)将首先被清理。这在逻辑上是错误的。main函数是在所有其他函数返回后最后被清理的函数。 我认为这本书有一个错别字。 - Raildex
Ataxias所添加的强调有帮助,但我仍然认为说明为什么你质疑最后一行会提高你的问题的表述。 - JaMiT
2个回答

3
这是一个错误。根据定义,一个堆栈是后进先出(LIFO)的数据结构。先进先出(FIFO)的数据结构应该是队列,而不是堆栈。

1
让我向您展示一下调用栈的工作原理:想象一下您有一个程序,其中包含一些函数和子函数,例如f1()f1.1()f1.2()f1.1.1()f1.2.1()f1.2.2(),并且您有以下代码片段:
int f1(){
  if (<condition>){ // B1
    return f1.1();
    } else {
    return f1.2();
  }
}

int f1.1(){
  int temp = -1; // B2
  return f1.1.1();
}

int f1.2(){
  if <other_condition>{
    return f1.2.1(); // B3
  } else {
    return f1.2.2();
  }
}

int f1.1.1(){
  int temp = 1001001;
  return temp;
}

int f1.2.1(){
  int temp = 1002001;
  return temp;
}

int f1.2.2(){
  int temp = 1002002; // B4
  return temp;
}

B1-B4表示在那一行设置了断点,执行时会命中这些断点。让我们看看此时调用栈的样子:

B1:调用栈:

f1()

B2: 调用栈:
f1.1()
f1()

B3: 调用栈:
f1.2() // at the moment of the breakpoint, f1.2.1() not yet executed.
f1()

B4: 调用堆栈:
f1.2.2()
f1.2()
f1()

调用栈从底部到顶部填充:首先添加f1()(该函数正在执行),当子函数(f1.1()f1.2())被执行时,该函数将被添加到调用栈的顶部。一旦执行完成,它就会被删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接