堆栈指针应该指向顶部的值,还是指向下一个值的位置?

时间:2016-06-08 11:52:21

标签: c arrays pointers stack

例如,以此示例函数为例:

#include <stdlib.h>

#define MAX 100
typedef struct stack {
int sp;
int val [MAX];
} STACK;


void initStack (STACK *s){
    s->sp = 0;
}

int push (STACK *s, int x){
    if(s->sp == MAX) return -1;
    else s->val[s->sp++] = x;
    return 0;
}

int main(){
    STACK s;
    int pushval, p;

    initStack(&s);

    p = push(&s, 1);
    pushval = s.val[s.sp-1];
    printf("pushval %d\n", pushval);

    return 0;
}

所以在这种情况下,如果我做s.val [s.sp],我会得到胡言乱语。如果我做s.val [s.sp-1]我得到了我推到堆栈的值。我不知道堆栈指针是否应指向&#34;下一个可用空间&#34;又名等于数组中元素的数量应该等于数组的最后一个元素的索引,又名数组中的元素数 - 1

2 个答案:

答案 0 :(得分:3)

这只是一个惯例问题。许多实现允许顶部堆栈指针指向&#34;下一个可用空间&#34;,但是你可以真正做你喜欢的事情,前提是你的堆栈外部表现得有意。

答案 1 :(得分:1)

对我来说,基于数组的堆栈最自然的实现是“向下”增长,堆栈指针指向最近推送的元素:

void initStack (STACK *s)
{
    s->sp = MAX;
}

int push (STACK *s, int x)
{
  if( !s->sp ) 
    return 0;               
  else                      
    s->val[--s->sp] = x;    
  return 1;                 
}    

int pop(STACK *s, int *x)
{
  if ( s->sp == MAX )
    return 0;
  else
    *x = s->val[s->sp++];
  return 1;
}

检查是更简单的IMO,并且因为它永远不会减少到0以下,你可以安全地使用无符号类型作为堆栈指针(我倾向于这样做可能不是完全合理的原因)。

请注意,这模仿了x86(和许多其他架构的)堆栈行为,因为SP向下“向下”,朝向0增长。

请注意,我在成功和失败时更改了返回值,因为在C 0中表示“false”,非零表示“true”。这样你就可以编写像

这样的代码
if ( push( stack, val ) )
{
  ...
}
else
{
  // push failed, handle as appropriate
}

同样,这只是一个更自然的IMO实现。