我正在学习数据结构课程,目前我在堆栈中遇到了困难。在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];
}
是用户定义的数据类型。
答案 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];
}