【问题标题】:Why is the pop function not running with stack[*top--] but working with with stack[*(top--)]?为什么 pop 函数不与 stack[*top--] 一起运行,而是与 stack[*(top--)] 一起运行?
【发布时间】:2021-11-17 22:25:11
【问题描述】:

问题是我无法使用弹出功能。

int pop(int stack[],int *top,int item)
{
    if(*top==-1) {
        printf("Stack Underflow");
        return 0;
    }
    return stack[(*top)--]; 
}

在这里,如果我使用stack[*top--],它似乎不起作用!有什么区别?为什么 main 函数中的 top 变量没有递减?

int main()
{
    int stack[4], top = -1, item, id, ch;
    for(;;) {
        printf("Enter your choice:\n1.push\n2.pop\n3.Print top element\n4.Print all elements\n5.Exit\n");
        scanf("%d",&ch);
        
        switch(ch) {
        case 1:
            printf("Enter the item to be pushed:\n");
            scanf("%d",&item);
            push(stack,&top,item);
            break;
        case 2:
            id=pop(stack,&top,item);
            printf("%d was popped\n",id);
            break;
        case 4:
            print(stack,&top,item);
            break;
        case 5:
            exit(0);
        }
    }
}

【问题讨论】:

  • 您刚刚了解了为什么将三个操作塞进大约 10 个字符的代码中是一个非常糟糕的主意。您的大脑实际上无法同时处理超过 3 到 5 个状态的复杂性,您只需将三个操作放入 10 个字符中,这些字符也位于执行函数返回语句的行上。如果有人教你写这样的代码,我敢打赌,他们从来没有待过电话,等到凌晨从家里接到电话,只是为了紧急修复这种过于复杂的代码会造成错误。
  • 这里的另一课是关于数据类型的良好封装。这些pushpop 函数具有糟糕的宽接口,要求调用者同时传递堆栈和堆栈指针,这意味着堆栈指针必须通过引用传递,以便函数可以修改它。相反,如果有适当的堆栈数据类型,某种struct stack,并且如果传递了指向该结构的指针,事情就会变得更简单、更清晰。 (当然,在 Chiranjit Debnath 所学课程的这个阶段,可能还没有引入结构。)
  • @AndrewHenle 许多平庸的 C 教师似乎是一个几乎神秘的永恒链条的一部分,将他们自己被误导的教师教给他们的不幸的学生传授给他们同样被误导的课程,他们从他们的在他们面前被误导的导师。这些被误导的教师都没有资格进行“真正的”编程,或者向学生教授“真正的”编程;充其量他们可以教育下一批被误导的教师,并且循环继续......

标签: c function switch-statement stack underflow


【解决方案1】:

在 C 中,所有后缀运算符的优先级高于所有前缀(或中缀)运算符。这就是定义语言的方式。所以

*top--

等价于

*(top--)

如果你愿意

(*top)--

您需要显式括号。

【讨论】:

    【解决方案2】:

    (*top)-- 所做的是:

    1. 取消引用top,即访问top指向的值。
    2. 递减该值。

    *top-- 所做的是:

    1. 递减top,即top本身的值
    2. 取消引用该值。

    除此之外,我认为最好定义一个堆栈结构,而不是使用原始数组和整数作为指针。

    #define STACK_CAPACITY 3 // Adjust it as you want
    
    struct stack {
        int items[STACK_CAPACITY];
        int top;
    };
    
    void stack_init(struct stack *s)
    {
        s->top = -1;
    }
    
    int stack_push(struct stack *s, int item)
    {
        if (s->top == STACK_CAPACITY-1)
            return 0; // fail: stack is full
    
        s->items[++s->top] = item;
        return 1; // success: item pushed
    }
    
    int stack_pop(struct stack *s, int *top)
    {
        if (s->top == -1)
            return 0;
    
        if (top != NULL) // if top is NULL, ignore it
            *top = s->items[s->top];
    
        s->top--;
        return 1;
    }
    

    这里是你如何使用它:

    int main()
    {
        struct stack s;
        stack_init(&s);
    
        if (!stack_push(&s, 1))
            printf("Stack is full\n");
        
        if (!stack_push(&s, 2))
            printf("Stack is full\n");
        
        if (!stack_push(&s, 3))
            printf("Stack is full\n");
        
        if (!stack_push(&s, 4))
            printf("Stack is full\n");
        
        if (!stack_push(&s, 5))
            printf("Stack is full\n");
    
        int item;
        stack_pop(&s, &item);
        printf("top = %d\n", item); // outputs 3
    
        stack_pop(&s, NULL); // Ignore the top
    
        stack_pop(&s, &item);
        printf("top = %d\n", item); // outputs 1
        
        if (!stack_pop(&s, NULL)) {
            printf("Stack is empty: cannot pop\n");
        }
    }
    

    另外,不要使用scanf() 来读取用户输入。 fgets() 更安全。

    【讨论】:

      【解决方案3】:

      return stack[(*top)--];
      here if I use [*top--]

      (*top)-- 获取top 指向的对象并递减该对象。因为*top 指向调用者的top,所以这是您要用于查找数组元素的值。然后-- 递减调用者的top,使其指向堆栈中的下一个最新项。

      *top--*(top--),它递减top,得到未递减值指向的对象。这也获得了调用者的top,但它减少了函数的本地top,而不是调用者的对象。因为函数的top递减,不再指向调用者的top

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-23
        • 1970-01-01
        • 1970-01-01
        • 2018-10-06
        • 2017-10-11
        • 2015-06-02
        • 1970-01-01
        • 2013-08-13
        相关资源
        最近更新 更多