这两种不同的StackTop函数实现有什么区别?

时间:2017-06-28 15:31:27

标签: c stack structure

我正在学习数据结构课程,目前我在堆栈中遇到了困难。在a函数的实现中(它在某种意义上复制或者#34; 返回"堆栈中的顶部元素而不影响堆栈。)下面的代码是它的实现,很明显,

StackTop

但是只要我们想给用户提供堆栈中top元素的值,我们不能像这样做这个函数吗?如果是这样,那么这两种实现之间的区别是什么?

void StackTop(StackEntry *pe, Stack *ps){
    *pe=ps->entry[ps->top-1];
}

请注意,StackEntry StackTop(Stack *ps){ return ps->entry[ps->top-1]; } 是用户定义的数据类型。

2 个答案:

答案 0 :(得分:3)

任何一个都可以使用。主要区别在于完成的副本数量。

在第一种情况下,结果值通过指针取消引用直接写入目标变量。在第二种情况下,值(在大多数实现中)放在堆栈上,然后复制到接收返回值的变量,假设返回值已分配。

对于返回值的情况,假定返回结构,编译器可能不会将返回值复制到堆栈,而是复制到其他位置并将指针放到堆栈上的该位置。这完全取决于实施。在任何一种情况下,结构数据都被复制两次。如果结构相对较小,则不应该是一个可测量的差异,尽管如果结构是几兆字节,它可能会变得很重要。

答案 1 :(得分:2)

这两个功能都没有很好的设计。这两个函数的问题是堆栈可能是空的。在这种情况下,函数具有未定义的行为,并且很难确定是否是这种情况。

在C中,更好的函数定义可能看起来像

int StackTop( Stack *ps, StackEntry *pe )
{
    int success = ps->top != 0;

    if ( success )
    {
        *pe = ps->entry[ps->top-1];
    }

    return success;
}

如果您不关心函数的未定义行为,因为还有一个函数报告堆栈是否为空,那么您应该考虑另外一个函数实现,它将允许更改存储在堆栈中的值。这样的功能看起来像

StackEntry * StackTop(Stack *ps)
{

    return &ps->entry[ps->top-1];
}