老师第一次向我介绍 C++ 时,第一个定义是关于“基于堆栈的语言”,如 Java、C 和 C++。
现在我在回复中读到了这个,老实说我很困惑。
C++ 是一种基于堆栈的语言,但不需要堆栈?
当我听到“基于堆栈的语言”时,我通常会想到像 FORTH 这样的语言,其中一切都在堆栈上完成,即没有变量。我猜当你的老师说 Java 时,他们的意思是基于堆栈的 JVM。
现在,C++ 标准完全没有堆栈或堆的概念,只有自动和动态存储之类的东西。C++ 是根据更抽象的概念来指定的,这使得它理论上可以在许多不同的实现和硬件上工作。当然,事实证明这些想法直接映射到堆栈的想法,因此每个实现最终都使用一个。
C++(如 C、Java 和大多数其他块结构语言)需要一个“堆栈”,即某种后进先出数据结构,用于保存函数调用的激活记录。也就是说,一个函数可以递归地调用自己到任意深度,并且当它这样做时,每次调用的参数/局部变量必须独立于先前调用的参数/局部变量。当这些函数调用返回时,必须销毁每个函数的参数/局部变量。
然而,这并不需要在直接支持硬件堆栈的 CPU 上执行。完全有可能在没有直接硬件支持的情况下执行 C++(以及上面提到的其他块结构语言)。
例如,早期的 Cray 和(甚至是当前的)IBM 大型机不支持堆栈。尽管如此,他们可以并且确实支持 C++。至少在大多数情况下,用于激活记录的 LIFO 数据结构是动态分配的,并构建成一个链表。当每个函数被调用时,它的激活记录被分配并添加到链表中。当函数返回时,该激活记录将从列表中删除并释放内存。
因此,如果您从某种抽象的角度看待事物,将堆栈视为它提供的基本操作的本质,那么是的,C++ 需要堆栈。如果您不那么抽象地看待“堆栈”,并考虑诸如带有堆栈指针寄存器(或该顺序的任何东西)的CPU之类的东西,那么不,C ++绝对不需要堆栈(对于C,Java也是如此, ETC。)
非“基于堆栈的语言”不仅仅是一种不需要堆栈的语言。
Java 的字节码语言是一种基于堆栈的语言,因为它的操作不是对寄存器进行操作,而是对堆栈进行操作。另一方面,英特尔微处理器的 ASM 语言使用寄存器,这可能反映在为编译到该架构而设计的语言中。
C 和 C++ 可能是也可能不是基于堆栈的。这完全取决于编译器和目标操作系统/微处理器。你不能假设它是或不是。然而,在实践中,它主要是作为基于寄存器的。
即使该语言完全使用寄存器操作,您仍然有一个堆栈用于函数调用和不适合寄存器的局部变量。该堆栈的存在不会使语言基于堆栈,而是缺少寄存器。
编辑:用户 mikera 建议的 Nitpick:Java 的字节码语言是基于堆栈的,但为了在大多数基于寄存器的体系结构中运行它,您需要在基于寄存器的体系结构中翻译基于堆栈的字节码语言. 这项工作可以由 JVM 中的解释器完成,也可以由 JIT 或非 JIT 字节码到本地编译器完成。
它是语义。
想想一辆车。一辆车是用收音机、速度、电动座椅、CD 播放器、杯架数量、油漆颜色等来描述的。功能列表并没有讨论运行所有这些东西的动力来自哪里。几乎所有汽车都使用汽油进入内燃机,发动机转动车轮并运行发电机以产生电力来运行所有配件。不需要发动机,但大多数汽车都有。
语言规范谈到了数据的生命周期。它没有说明生命周期是如何实现的。事实证明,99% 的 C++ 编译器使用全局数据、堆栈和堆来满足语言规范所需的数据生命周期要求。