【问题标题】:Stack in C. Storing pop ant top resultsStack in C. 存储 pop ant top 结果
【发布时间】:2016-10-23 00:45:15
【问题描述】:

考虑一个堆栈,最多有 100 个整数。定义为:

#define MAX 100

typedef struct stack {
    int size;
    int values[MAX];    
} STACK;

我有这个弹出功能:

int pop(STACK *s, int *x){
    if (s->size == 0) return 1;

    int *p = s->values + s->size--;
    *x = *p;

    return 0;
}

应该删除 values[MAX] 最后一个元素,将该值存储在 x 地址,如果成功则返回 0;

其他功能:

int top(STACK *s, int *x){
    if (s->size == 0) return 1;

    int *p = s->values + s->size;
    *x = *p;

    return 0; 
} //like pop function, it should store top element at address x.


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

int push(STACK *s, int x){
    if (s->size >= MAX) return 1;

    int *p = (s->values);
    *(p + s->size++) = x;

    return 0;
}

这是我的主要内容。它仅在第一次弹出呼叫时失败:

int main(){
    struct stack s;
    STACK *p = &s;
    int i;
    int x,y,z,w,t;

    initStack(p);

    for(i = 0; i < MAX; i++)
        push(p,i);

    int res = push(p,MAX);

    for(i = 0; i < MAX; i++)
        printf("%d|", p->values[i]);

    printf("\nLast insertion: %d",res);

    pop(p,&x);
    pop(p,&y);
    pop(p,&z);
    pop(p,&w);
    top(p,&t);

    printf("\nThe elements %d|%d|%d|%d were removed. Current stack size: %d . Top element: %d.",x,y,z,w,p->size,t);

    return 0;
}

结果(仅最后一个 printf):

The elements 1|99|98|97 were removed.Current stack size: 96 .Top element: 96.

由于某种原因,第一次 pop 调用失败, 这不仅会谴责已删除元素的列表,还会谴责顶部元素的结果。 有什么建议吗?

【问题讨论】:

  • push 呢?
  • 而且不要这样做:int *p = s-&gt;values + s-&gt;size-- 请。
  • 顺便说一句,pop 正在使用valuessizetop 正在使用 tamanhovalores。你真的需要发布 MCVE。
  • 您使用显式指针算法混淆代码而不使用索引运算符[]的任何原因?
  • 什么是MAX?你为什么改用100

标签: c struct stack


【解决方案1】:
  1. 您将MAX+1 元素推入堆栈,因为循环将MAX 元素推入堆栈,循环之后还有一个push 调用。
  2. 您的pop 实现不正确,因为以下行:

    int *p = s->values + s->size--;
    

    指针p 将指向s-&gt;values[s-&gt;size] 而不是s-&gt;values[s-&gt;size-1],因为s-&gt;size 的递减将在评估和分配给p 之后发生。

  3. 在表达式中使用自增/自减运算符理所当然地被认为是不好的做法,并且由于这类错误而强烈反对。

  4. 如果可能,使用索引运算符[] 而不是像这样的指针算术会更易读且不易出错:

    int
    pop(STACK *s, int *x) {
       if (s->size == 0) {
         return 1;
       }
    
       s->size--;
       *x = s->values[s->size];
    
       return 0;
    }
    

【讨论】:

  • 最后push好像是测试错误情况,所以特意放在这里。
  • 是的,我认为可能是这样,但如果不是,我想指出这一点。
【解决方案2】:

我支持那些对代码清晰度发表评论的人。如果您使用的是数组,那么如果您使用[] 索引而不是指针算法,那么您遇到问题的可能性就会大大降低。

也就是说,我认为问题在于pop 存在越界问题。在你推入mains-&gt;size==MAX 中的MAX 元素之后。所以pop访问*(s-&gt;values + MAX) == s-&gt;values[MAX],其实就是数组末尾之后的元素。该数组从0 运行到MAX-1,而不是从1MAX。例如,如果size==1,你实际上想要s-&gt;values[0],第一个元素,而不是不存在的s-&gt;values[1]

最小更改为int *p = s-&gt;values + --s-&gt;size;,但我同意这不是解决问题的正确方法。相反,请使用*x = s-&gt;values[s-&gt;size-1]; --s-&gt;size;

【讨论】:

  • 为什么第二种方案比第一种方案好?
  • 我的看法:因为(1)它对数组使用了数组索引操作符[],比使用指针操作更清晰; (2)它将索引与减量分开,这也更清晰(并且更容易在调试器中单步执行!); (3) 它更清楚地将代码与您实际想要做的事情联系起来:获取一个项目 ([]) 并更改大小 (--)。
猜你喜欢
  • 2012-08-25
  • 1970-01-01
  • 2023-01-15
  • 2021-11-17
  • 2020-11-26
  • 2017-04-02
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多