cfunctionswitch-statementstackunderflow

Why is the pop function not running with stack[*top--] but working with with stack[*(top--)]?


The problem is that I am unable to use the pop function.

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

Here, if I use stack[*top--] it doesn't seem to work! What is the difference? Why is the top variable in the main function is not getting decremented?

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);
        }
    }
}

Solution

  • What (*top)-- does is:

    1. Dereferences top, i.e. accesses the value which top is pointing to.
    2. Decrements that value.

    What *top-- does is:

    1. Decrements top, i.e. the value of top itself
    2. Dereferences that value.

    Besides that, I think it would be better if you define a stack structure instead of using a raw array and an integer as a pointer.

    #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;
    }
    

    Here is how you can use it:

    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");
        }
    }
    

    Also, don't use scanf() to read user input. fgets() is much safer.