如何创建和处理堆栈?

时间:2012-01-12 15:56:32

标签: c stack

因为来自C ++及其他地方的任何东西都有很好的构造来处理类似行为的“堆栈”(向量,列表,数组列表等),所以我想用C来保持这个问题。

所以,我正在学习编译器,堆栈,inscript和postscript,解析器,词法分析器以及涉及将编译器放在一起的所有其他内容,因为我将在本学期的课程中稍后要求。我想确保我对堆栈的理解是可靠的。

我相信我对如何组合在一起有一个总体思路。基本上你有一个遵循LIFO模型的数组。添加元素时,它会被“推入”到数组的末尾,并在删除时“弹出”。没问题。我关注的是一些实现细节。 如何跟踪元素数量?堆栈初始化到多大?我应该使用结构来保存这些细节吗?变量是全局的吗?

我的教授已经向我们提供了与我们的任务相关的一些源代码,我只是为了自己的理解寻找一些补充细节(通常我必须在获得理解之前自己整理一些内容别人的代码)在我的大多数编程经验中,堆栈是一些我无法控制的神奇之处,但如果我的递归函数太深(如果有人那么?)会爆炸。

提前致谢。

修改

好吧,我认为我需要澄清的一件事是我没有制作一个“真正的”堆栈,但是需要采用一个中缀epxression并将其转换为postfix。我正在查看堆栈数据结构,因此任何与architecure相关的内容可能都不适用于此。我得到的印象是堆栈是处理这种情况的方式,同样通过BNF表示法中描述的规则缩减。

3 个答案:

答案 0 :(得分:5)

你在谈论什么样的堆栈?

大多数CPU架构都有堆栈的概念,这就是CPU基本上跟踪函数调用的方式。 C通常被编译为为此目的使用相同的堆栈,并且经常使用它来进行参数传递。

这种“架构”堆栈并不需要太多,通常在CPU中有一个指向堆栈顶部的寄存器。操作系统的工作是确保每次进程启动时,该进程都有一个有效的堆栈指针。这是通过分配存储器并将寄存器初始化为适当的地址来完成的。现代“大型”操作系统:具有虚拟内存等等,通常支持按需动态增长堆栈。

在这种情况下,不会显式跟踪堆栈中的元素数量,您可以通过检查当前堆栈指针并与进程'(假设已知)进行比较来计算所使用的 bytes 的数量stack start“,但这并没有告诉你这些字节的内部结构。对于这种低级构造,这是正常的。


如果正如nos在评论中提示的那样,你真的在​​谈论堆栈数据结构,那么在C中就没有标准的实现。可以想象许多可能的API:例如:< / p>

typedef struct _Stack Stack;

Stack * stack_new(size_t element_size, size_t initial_depth, int allow_growth);
int     stack_push(Stack *stack, const void *element);
int     stack_pop(Stack *stack, void *element);
void    stack_peek(const Stack *stack, void *element);
size_t  stack_depth(const Stack *stack);
void    stack_clear(Stack *stack);

上述API保留了初始深度,一旦您尝试超出限制直到用户,堆栈是否应该增长。在我看来,这对于通用API来说是明智的。

答案 1 :(得分:2)

好像你可能正在寻找调用堆栈的信息。 在这种情况下,这篇文章可能会帮到你很多。

http://altdevblogaday.com/2011/12/24/c-c-low-level-curriculum-part-4-more-stack/

这个和前一个(在帖子中链接)讨论了堆栈如何在汇编级别工作。这是必要的,因为即使C在你创建函数时也会将它隐藏起来。

从编译器的角度来看,这可能是最相关的,但可能是堆栈最重要的实现。

答案 2 :(得分:0)

应将堆栈初始化为多大?

我认为属于您的用例。

如何追踪元素数量?

您可以将信息存储在额外的变量中,或每次都计算元素。