例 12.1. 用堆栈实现倒序打印
运行结果是cba
。运行过程图示如下:
数组stack
是堆栈的存储空间,变量top
总是保存数组中栈顶的下一个元素的下标,我们说“top
总是指向栈顶的下一个元素”,或者把top
叫做栈顶指针(Pointer)。在中介绍了Loop Invariant的概念,可以用它检验循环的正确性,这里的“总是指向栈顶的下一个元素”其实也是一种Invariant,Push和Pop操作总是维持这个条件不变,这种Invariant描述的对象是一个数据结构而不是一个循环,在DbC中称为Class Invariant。Pop操作的语义是取出栈顶元素,但上例的实现其实并没有清除原来的栈顶元素,只是把top
指针移动了一下,原来的栈顶元素仍然存在那里,这就足够了,因为此后通过Push和Pop操作不可能再访问到已经取出的元素,下次Push操作就会覆盖它。putchar
函数的作用是把一个字符打印到屏幕上,和printf
的%c
作用相同。布尔函数is_empty
的作用是防止Pop操作访问越界。这里我们预留了足够大的栈空间(512个元素),其实严格来说Push操作之前也应该检查栈是否满了。
例 12.2. 用递归实现倒序打印
也许你会说,又是堆栈又是递归的,倒序打印一个数组犯得着这么大动干戈吗?写一个简单的循环不就行了: