Thread: Is My Interpretation of This Program Implementing a Stack Correct?

  1. #1
    Registered User
    Join Date
    Dec 2016
    Posts
    45

    Is My Interpretation of This Program Implementing a Stack Correct?

    I made it to the chapter in my book on program organization. It also introduced the concept of the stack data structure and gave this example program. Full code and question text is below

    I have two questions

    1). Is my interpretation of how the array gets filled out as a stack according to the code below correct? Does it go from left to right with this? Am I incremented the stack "top" pointer correctly. I had to draw this out because the book doesn't always give perfectly explicit explanations.

    I put some sample input in the black box and outlined the steps that I believe the program executes

    Full res picture link: http://i.cubeupload.com/NahJbi.jpg

    Is My Interpretation of This Program Implementing a Stack Correct?-steps-jpg





    2). I tried "stepping" through the program in Visual Studio and could not get the console to display the prompt I want to start the main loop. Did I position the break point correctly?

    I've noticed that I'm not able to step through certain programs to see what all the variables and array elements are at a given time.

    Is there a reason for this I'm overlooking? Attached screenshots of my attempt on this image host: http://i.cubeupload.com/NDhMz9.jpg

    Is My Interpretation of This Program Implementing a Stack Correct?-question-jpg





    Code:
    #include <stdbool.h>#include <stdio.h>
    #include <stdlib.h>
    
    
    #define STACK_SIZE 100
    
    
    char contents[STACK_SIZE];
    int top = 0;
    
    
    void make_empty(void);
    bool is_empty(void);
    bool is_full(void);
    void push(char c);
    char pop(void);
    void failure(void);
    void stack_underflow(void);
    void stack_overflow(void);
    
    
    int main(void)
    {
        char c;
    
    
        printf("Enter parentheses and/or braces: ");
        while ((c = getchar()) != '\n') {
            if (c == '(' || c == '{') {
                push(c);
            }
            else if (c == ')') {
                if (pop() != '(')
                    failure();
            }
            else if (c == '}') {
                if (pop() != '{')
                    failure();
            }
        }
    
    
        if (is_empty())
            printf("Parentheses/braces are nested properly.\n");
        else
            failure();
    
    
        return 0;
    }
    
    
    void make_empty(void)
    {
        top = 0;
    }
    
    
    bool is_empty(void)
    {
        return top == 0;
    }
    
    
    bool is_full(void)
    {
        return top == STACK_SIZE;
    }
    
    
    void push(char i)
    {
        if (is_full())
            stack_overflow();
        else
            contents[top++] = i;
    }
    
    
    char pop(void)
    {
        if (is_empty())
            stack_underflow();
        else
            return contents[--top];
    }
    
    
    void failure(void)
    {
        printf("Parentheses/braces are not matched.\n");
        exit(0);
    }
    
    
    void stack_underflow(void)
    {
        failure();
    }
    
    
    void stack_overflow(void)
    {
        printf("Stack overflow\n");
        exit(1);
    }


    Exercise Question:

    1). Modify the stack example so that it storescharacters instead of integers. Next, add a main function that asks the user toenter a series of parentheses and/or braces, then indicates whether or notthey're properly nested.

    Enter parentheses and/or braces: (() {} { () } )
    Parentheses/braces are nested properly


    Hint: as the program reads characters, have it pusheach left parenthesis or left brace. When it reads a right parenthesis orbrace, have it pop the stack and check that the item popped is matching theparenthesis or brace. (If not, the parentheses/braces aren’t nested properly)

    -When the program reads thenew-line character, have it check whether the stack is empty; if so, theparentheses are matched. If the stack isn't empty (or if stack_underflow is ever called), theparentheses/braces aren't matched.

    -If stack_overflow is called, havethe program print the message Stack overflow and terminate immediately
    Last edited by potomac; 12-22-2016 at 01:03 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Try putting your breakpoint on line 39.

    And your interpretation seems to be wrong.
    Each open bracket or brace pushes onto the stack.
    Each close bracket or brace pops a (hopefully) corresponding open off the stack.

    When you're done, the stack should be empty.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Dec 2016
    Posts
    45
    Breakpoint 39 solved it! I'll have to remember that the issue with my breakpoints is always an "off by one line" of sorts!

    So is the array only ever filled with one character or two characters in this case? (Located at element zero and one)

    Is setting the array size at 100 way overkill then?
    Last edited by potomac; 12-22-2016 at 02:24 PM.

  4. #4
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by potomac View Post
    So is the array only ever filled with one character or two characters in this case? (Located at element zero and one)
    If by "array" you mean the stack, then no, it can be filled with an arbitrary number of chars. Consider the input string "(((((((((())))))))))". That will use 10 positions.
    Here's another example:
    Code:
    Stack :
    String: ( ( { } { { } } ) )
    
    Stack : (
    String: ( ( { } { { } } ) )
            ^
    Stack : ( (
    String: ( ( { } { { } } ) )
              ^
    Stack : ( ( {
    String: ( ( { } { { } } ) )
                ^
    Stack : ( (
    String: ( ( { } { { } } ) )
                  ^
    Stack : ( ( {
    String: ( ( { } { { } } ) )
                    ^
    Stack : ( ( { {
    String: ( ( { } { { } } ) )
                      ^
    Stack : ( ( {
    String: ( ( { } { { } } ) )
                        ^
    Stack : ( (
    String: ( ( { } { { } } ) )
                          ^
    Stack : (
    String: ( ( { } { { } } ) )
                            ^
    Stack :
    String: ( ( { } { { } } ) )
                              ^

  5. #5
    Registered User
    Join Date
    Dec 2016
    Posts
    45
    I get the idea of a basic stack (LIFO), but this program's execution has me flummoxed.

    Is there a way I can modify my code so that I can see the values contained in the stack as I step through it? Also, the value of the "top" pointer. I thought that stepping through with those visible might help.

    Currently, Visual Studio is only showing the value of variable c, and the returned pop. Like this: Is My Interpretation of This Program Implementing a Stack Correct?-pop-jpg

    I tried moving these variables into the main loop, but they of course are external, and that throws the other functions.

    I think the root of the problem is the debugger only shows variables that are in the block scope of the main loop

  6. #6
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by potomac View Post
    I get the idea of a basic stack (LIFO), but this program's execution has me flummoxed.
    My example is not just a "basic stack"!
    It's exactly your program in operation.
    String is the input string.
    The little pointer under it shows the current string position.
    Stack shows the current contents of the stack.
    When you see an opening bracket, push it onto the stack.
    When you see a closing bracket, pop the top of the stack and see if it's the matching opening bracket. If it doesn't match, then the brackets don't match.
    If you reach the end of the string and the stack isn't empty, then the bracket's don't match.
    It's really very simple.
    You may be overthinking it!

    Anyway, your "contents" and "top" variables are global, so you should be able to see them all the time. You could add print statements to print them out after every modification (you don't always have to use a debugger).

  7. #7
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Here's an example of using some fancy print statements instead of the debugger. The blue numbers are indices, the yellow numbers are values, and the red numbers are values whose final positions have been determined.

    However, the code to do this is probably twice as long as the quicksort code itself!

    Is My Interpretation of This Program Implementing a Stack Correct?-qsort-png

  8. #8
    Old Took
    Join Date
    Nov 2016
    Location
    Londonistan
    Posts
    121
    If globals don't show in the auto window then add a watch to them, check the debug menu for watch and add the variable manually.

  9. #9
    Old Took
    Join Date
    Nov 2016
    Location
    Londonistan
    Posts
    121
    Once you have the code working properly and you can follow what's going on, another exercise for you would be to remove the globals, define them in main and pass them though the functions. You'll need to work out what changes need to be made to make that work. I hope your book has explained parameter passing and function prototypes and scope well.
    And yes a stack is like a stack of paper where you are only allowed to remove one sheet at a time from the top or place a sheet on top, it is as you describe a LIFO data structure.
    I've never liked K&R block structure. C programmers love it, but I much prefer my braces to all line up so I can spot missing braces instantly.
    Where you are doing this....
    Code:
    int func() {
       ///.......
    }
    I prefer
    Code:
    int func()
    {
       //......
    }
    Purely stylistic and uses a bit more vertical space than K&R style but personally I think enhances readability.

  10. #10
    Registered User
    Join Date
    Dec 2016
    Posts
    45
    Thanks for the tip on "Watch"

    I was able to add one for the array

    Is My Interpretation of This Program Implementing a Stack Correct?-untitled-picture-jpg

  11. #11
    Registered User
    Join Date
    Dec 2016
    Posts
    45
    I managed to trace the array and variable c in Visual Studio

    It looks like this is the trace for: (){}

    So it doesn't look like the array is totally clear at the end. Also, the array never has more than 1 element filled in with data from variable c


    Is My Interpretation of This Program Implementing a Stack Correct?-cc-jpg
    Last edited by potomac; 12-23-2016 at 12:10 PM.

  12. #12
    Registered User
    Join Date
    Dec 2016
    Posts
    45
    Here's a PDF showing what I saw on my screen in my debugger. File was 2.5 mb and I couldn't upload it to the board: https://www.pdf-archive.com/2016/12/23/walkthrough/

    It's showing that the stack is never fully cleared at the end in the Watch area

    Also, the ( doesn't get cleared properly in the Watch area when pop() is called

  13. #13
    Old Took
    Join Date
    Nov 2016
    Location
    Londonistan
    Posts
    121
    Why would you think the array would be cleared?

    Look at what the pop function does.

    Is the array empty? If yes, crap out, can't pop from an empty stack.

    If not subtract one from top and return the value at that location. There's no zeroing after pop or any altering of the array so any data placed in there will stay in there until overwritten by new data.

  14. #14
    Registered User
    Join Date
    Dec 2016
    Posts
    45
    Hobbit, the comment about the array not zeroing out is helpful. I didn't think to consider that the data stays there in memory until written over

    So the result I'm seeing it entirely consistent with what Salem said in post #2

  15. #15
    Old Took
    Join Date
    Nov 2016
    Location
    Londonistan
    Posts
    121
    Yeah.

    You have a 100 slot array, space for 100 items on the stack and an index into that array known as top which is one past the last pushed element, i.e. it points to the next location an item will be pushed onto the stack. If you push 20 items onto the stack and remove 18 with pop, your stack will be array[0] to array[1] and top will be 2. Push four more items and your stack runs from array[0] to array[5] and top will be 6. When the stack is empty top is zero. When the stack is full top is 100. Memory doesn't get automatically zeroed after use, whatever was last there is left there until overwritten, it is your responsibility to not go accessing stuff like top+1 which until top is 99 will be in the array but not in the stack. Do you get it?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C program, making a stack and implementing it
    By wright.joshua92 in forum C Programming
    Replies: 11
    Last Post: 07-03-2015, 05:53 PM
  2. Implementing stack using class template
    By Trey Brumley in forum C++ Programming
    Replies: 11
    Last Post: 12-05-2013, 10:50 PM
  3. Help implementing a stack
    By 9erNumber16 in forum C Programming
    Replies: 15
    Last Post: 04-12-2012, 11:23 PM
  4. Please ..err..nitpick my code (implementing a stack)
    By manasij7479 in forum C++ Programming
    Replies: 6
    Last Post: 10-04-2011, 05:20 PM
  5. implementing a stack with template
    By micha_mondeli in forum C++ Programming
    Replies: 5
    Last Post: 03-31-2005, 07:08 PM

Tags for this Thread