How to Implement a Stack in C (+ encapsulation)

Поділитися
Вставка
  • Опубліковано 30 тра 2024
  • Patreon ➤ / jacobsorber
    Courses ➤ jacobsorber.thinkific.com
    Website ➤ www.jacobsorber.com
    ---
    How to Implement a Stack in C (+ encapsulation) // This video shows you how to implement a stack two ways, in C - using an array and using a linked list.
    Also, I'm planning a new course for July 2020, aimed at beginning computer science/engineering/programming students. Interested? Join my mailing list to get more information in the coming days.
    jacobsorber.com/mailinglist/
    ***
    Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.
    About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.
    More about me and what I do:
    www.jacobsorber.com
    people.cs.clemson.edu/~jsorber/
    persist.cs.clemson.edu/
    To Support the Channel:
    + like, subscribe, spread the word
    + contribute via Patreon --- [ / jacobsorber ]
    + rep the channel with nerdy merch --- [teespring.com/stores/jacob-so...]
    Source code is also available to Patreon supporters. --- [jsorber-youtube-source.heroku...]

КОМЕНТАРІ • 107

  • @zachzulanas4125
    @zachzulanas4125 4 роки тому +54

    you are honestly the reason why I actually like C and understand it, your videos are so clear and concise, I wish I could have you as an actual professor!

    • @JacobSorber
      @JacobSorber  4 роки тому +6

      Thanks, Zach. Glad I could help. I'll be teaching OS this fall at Clemson, if you want to enroll. 🙂

    • @zachzulanas4125
      @zachzulanas4125 4 роки тому +1

      @@JacobSorber wish I could :( I'm at UCSC, and I'm in my Systems class rn, your videos have been a godsend, especially the threading series, our professor had us build a server with sockets but barely went over them in class, more just the concepts.

  • @axalius572
    @axalius572 4 роки тому +46

    You're the only person on youtube, I'd take an online course from.

    • @KorayUlusan
      @KorayUlusan 3 роки тому +1

      corey schafer's python playlist is awesome too!

    • @brijeshsamal7035
      @brijeshsamal7035 2 роки тому +1

      Jacob - go-to for learning C related stuff. Kevin Powell-CSS, Tech With Tim/ Corey Schaefer-Python. Most others are pretty random.

  • @dbgn
    @dbgn 4 роки тому +2

    Hi Jacob ,I found your channel recently and you are amazing teacher. Can you make more in depth tutorials about operating systems ,networks ,compilers for those of us ,who can't affort college. I really think you are amazing teacher ,your students are lucky.

  • @Mishiman
    @Mishiman 4 роки тому +11

    4:00 you could pass a pointer to an int to pop() so you can check for errors, like so
    int pop(int *error) {
    if (stack_empty) *error = 1; return 0;
    *error = 0; return value;
    }
    and then
    int error = 0;
    int value = pop(&error);
    if (error) { ... } else { // do something with the value... }
    It's a bit more verbose but I think that's the best solution

    • @yourf4104
      @yourf4104 5 місяців тому

      just use errno :D

  • @samuelrasquinha6712
    @samuelrasquinha6712 4 роки тому +2

    You really have a passion for code and teaching. Thanks a lot for these high quality, amazing and to the point videos. Good Luck.

  • @jakubstandarski7974
    @jakubstandarski7974 3 роки тому

    Amazing job! Everything clarified in a very simple way and accordance with words of Albert Einstein: Everything should be made as simple as possible, but not simpler.

  • @timwmillard
    @timwmillard 4 роки тому

    Thanks Jacob. Another great video.

  • @makanbanyak3957
    @makanbanyak3957 3 роки тому

    thanks for making videos.

  • @iversonvarun
    @iversonvarun 3 роки тому +1

    Love the content. I would rather be interested in a more advanced embedded systems/operating systems/C programming course.

  • @johnnewton2340
    @johnnewton2340 4 роки тому +16

    Great job! Could you make a video about "Difference between system call and function call" ?

    • @JacobSorber
      @JacobSorber  4 роки тому +8

      Absolutely. I just added it to my topic list.

    • @soumyadipsaha8904
      @soumyadipsaha8904 3 роки тому

      yes please

    • @marcossidoruk8033
      @marcossidoruk8033 3 роки тому +4

      Function call is when you call a function using the standard calling conventions (arguments should be pushed to the stack in reverse order, then the return adress, etc etc), a system call is when a program runs kernel code, there are two ways in wich this may happen:
      The progran triggers an interrupt, that is a specific CPU instruction that interrupts the execution of the program and passes control to the os or the firmware, the OS generally takes the arguments for the interrupt from the cpu registers.
      Interrupts are very slow thoug, so modern operating systems often load the part of the kernel code needed for syscalls into the memory allocated for the process, thus allowing the process to make systemcalls as if they were just another function without messing things up.

  • @anjalibhatt56
    @anjalibhatt56 4 роки тому +3

    Thank you for designing this course. Eagerly Waiting for it😇

  • @MrCiberedgar
    @MrCiberedgar 3 роки тому

    Hi Jacob!, I tried to implement the stacks with linked lists as you showed in the video, and everything worked like a charm, till I added a function that creates a dynamic array with malloc, now if I give that array a size bigger than the amount of elements in the stack it won't pop any element for some reason.
    Any tips on how to solve this?
    Amazing videos btw!

  • @dedswift
    @dedswift 4 роки тому +4

    Amazing video. Can you please do one about graphs ?

    • @JacobSorber
      @JacobSorber  4 роки тому +2

      Definitely. It's on the list of future video topics.

  • @rustycherkas8229
    @rustycherkas8229 2 роки тому

    @12:30 - If the array's stack index started at zero (index of first store location), and it was incremented after a successful copy ( ie: stack[ idx++ ] = value; ) there would be no "funny business" initialising to -1...
    Pre-decrement, if possible, when popping the top value off the stack: ( value = stack[ --idx ]; )
    idx is the (unsigned) count of the number of items currently on the stack.
    Bounds checking has been left as an exercise.

  • @sheikhsakibulhasib6208
    @sheikhsakibulhasib6208 3 роки тому

    Vai ... Shei SHei!!! AWESOME!!

  • @soumyadipsaha8904
    @soumyadipsaha8904 3 роки тому

    please make a video on block devices and interrupt handling

  • @GCAGATGAGTTAGCAAGA
    @GCAGATGAGTTAGCAAGA 19 днів тому

    Hi! Nice tutorials. But I can't understand something: in 10:23 you passed *mystack pointer into a pop function. Than inside this function you used star operator with an arrow operator - after dereferencing a pointer basically. Why is it so? I mean *mystack isn't even a double pointer.

  • @sukivirus
    @sukivirus 3 роки тому

    Hey Jason, great video! I am trying to follow your video creating stacks but I wish to create a stack for any data type. How can I do it please?

  • @sumitbhosale3401
    @sumitbhosale3401 4 роки тому +2

    Very Nice Explaination Sir. Thank You. Can You make video on graph in c. cause it is so hard to learn

    • @JacobSorber
      @JacobSorber  4 роки тому

      I'll add it to the list, and see what I can do.

  • @kc2838
    @kc2838 4 роки тому

    Eagerly waiting for your course. Plz Use C/C++ for the codes in the course also.

  • @R4ngeR4pidz
    @R4ngeR4pidz 4 роки тому +1

    for int pop() you could give it a pointer, if you can pop something you assign the value to that pointer, and return true
    otherwise you return false

    • @JacobSorber
      @JacobSorber  4 роки тому +1

      Hi Thijs. Good to see you again. Yes, you definitely can. I tried to keep things simple, so I don't confuse people who still are settling in with pointers. But, you're absolutely right.

  • @atkuriajaykumar3701
    @atkuriajaykumar3701 3 роки тому

    Thankyou sir I watched upto implementation with array since I don't know what is linked list .I will watch it and then come back.basically I don't know nothing about programming can you please suggest me what to do

  • @TinBryn
    @TinBryn 3 роки тому

    C actually has a really good encapsulation story, you can put in a header.
    struct stack;
    struct stack* new_stack();
    void push_stack(struct stack *mystack, int value);
    int pop_stack(struct stack *mystack);
    void delete_stack(struct stack* mystack);
    and that's it, with this you can write and compile (but not link) code using only this, not only do you not know the implementation, it doesn't even have to have been written at this point.

  • @gautamkumarshukla3055
    @gautamkumarshukla3055 3 роки тому +1

    At line number 14 , top++, we have incremented the index . Then setting the value at that index.
    Because of this we may miss the index 0 to set value at . I believe it should be " mystack[top++] = value;"

    • @sverkeren
      @sverkeren Рік тому +1

      No, empty stack has top=-1, so first push will land at index 0.

  • @zukunftentwickler3824
    @zukunftentwickler3824 3 роки тому

    Hi Jacob, thanks a lot for your great videos. I really like the setup you are using in visual studio code for your examples, can you just give more information about? Thanks in advance.

    • @JacobSorber
      @JacobSorber  3 роки тому

      Thanks, Herr Entwickler. So, just to clarify, you are looking for more information about my setup? It's pretty standard. Are there specific things you are wondering about?

  • @DreamVikings
    @DreamVikings Рік тому

    Hello. Im a scrub desperately researching stuff because i have an interview soon.
    I believe that by "encapsulation" you actually mean "abstraction". Encapsulation, as I understand it (This is from an OOP video I watched) relates to access levels, but presenting the information in a way that hides the back of the code from the user / programmer working on code, is abstraction.
    Again, im kind of new. Could be wrong.

  • @bonbonpony
    @bonbonpony 3 роки тому

    01:25 That's why I often use a metaphor of a one-ended pipe/tube ;> Because this disallows cheating. The only way to get something out of the bottom of a one-ended pipe is to first remove all the objects that are lying upon it, one by one.
    01:40 Well, there's also `peek`, which allows you to look at the element on the top of the stack without the need of removing it. Sure, it could be implemented with `pop` followed by a `push` of the same thing, but `peek`ing is faster and doesn't really break the invariants ;) Same thing with a variant of `peek` that can peek an `n`th element counting from the top of the stack, because it can be simulated with `n` calls to `pop` followed by `n` calls to `push` to restore the original layout of the stack. Another useful thing might be `dup` which duplicates whatever is currently on the top of the stack. This one is equivalent to popping it once, then pushing it twice. But yeah, in terms of interfaces, those could be implemented as external helper functions on top of `push` and `pop`, while `push` and `pop` are crucial. But I think there might be a couple of "methods" that are as crucial as `push` and `pop`, and can be considered a part of the stack's interface: checking whether it's full/overflown (unless it automatically grows), and checking whether the stack is empty (this one is quite crucial).

  • @alacastersoi8265
    @alacastersoi8265 3 роки тому

    Can you do a video on alignment in c and _Alignas?

  • @eugenek.9959
    @eugenek.9959 2 роки тому +1

    I have rewatched this part a thousand times and still struggling to understand... newnode -> next = head; head = newnode; what is that done for?

    • @JacobSorber
      @JacobSorber  2 роки тому +1

      Drawing it out might help. Basically, you're adding the newnode to the front of the list. You do that by pointing the newnode's next pointer to the current head. And, then you move the head pointer to point to the new node. So, in the end, you have your head pointer pointing at the new node, and the chain remains intact.

    • @eugenek.9959
      @eugenek.9959 2 роки тому

      @@JacobSorber Thank you very much for the reply. My main problem was that I imagined *next pointer of each node to point to new node that's being pushed, and not vice versa. I guess I've seen a lot of visualisations of stacks without actually saying that

  • @makveli259
    @makveli259 4 роки тому +5

    Algorithms in C?

  • @xwaazes6375
    @xwaazes6375 3 роки тому

    I suppose you could create a constructor method like
    stack* newStack(){ stack* this = malloc(sizeof(stack); this->top = STACK_EMPTY; return this;}.
    A little too C++-esque but I believe that makes the job.

  • @SimonJentzschX7
    @SimonJentzschX7 4 роки тому

    I love watching your videos. One Question about encapsulation: In order to keep the implementation flexible we don't want to make the details public. So many projects are using void* as types. In your example the functions pop() and push() could also use a void* (or a typedef to void*) instead. What do you think of this approach?

    • @JacobSorber
      @JacobSorber  4 роки тому +3

      Good question. I think it really depends on what you're trying to protect against. With void* you lose any type-checking help that the compiler could otherwise offer. And, it doesn't prevent people from messing with it, but rather just makes things opaque, which probably does discourage most people from messing with the internals. Whenever possible, I like to keep the compiler's type checking as an ally in my quest for robust code.

    • @SimonJentzschX7
      @SimonJentzschX7 4 роки тому

      @@JacobSorber I agree, so far we talked about it in the team but we did not want to lose the help of the compiler. One option though would be to havean public and an internal header file. And for the public header-file we could replace the struct-def with void, because when linking to a library you don't need the internal struct anymore.

    • @TheCocoaDaddy
      @TheCocoaDaddy 4 роки тому

      @@JacobSorber Yep, the compiler is your friend. :)

  • @ajilraju355
    @ajilraju355 4 роки тому

    Nice video

  • @jayflaherty5260
    @jayflaherty5260 4 роки тому +2

    Have you thought about exploring Rust as a programming language to help students write safe, performant, and concurrent systems level code?

    • @JacobSorber
      @JacobSorber  4 роки тому +1

      I have. I like Rust. As it becomes more mature and available on different platforms, it's definitely a solid option.

    • @jayflaherty5260
      @jayflaherty5260 4 роки тому

      @@JacobSorber it hit v1.0 5 yrs ago (1.45 now), async/await is now in the core, and Microsoft has WinRT, and its available on all platforms LLVM is available. Looking forward to more Rust videos!

  • @aabdev
    @aabdev 4 роки тому

    Dear Jacob Sorber
    ,
    What determines in which direction the RAM function-stack will grow?
    In my MCU (SPC58) stack grows from big RAM address to low RAM address.
    Is that HW determined?
    Is it possible to reverse function-call stack direction in compiler options?
    Warm regards,
    AB

    • @JacobSorber
      @JacobSorber  4 роки тому +1

      Since push and pop are usually operations defined by the architecture, this question is very hardware dependent. Some processors grow the stack upward (8051, I think), and some are selectable (ARM, I believe).

  • @brudra0
    @brudra0 Місяць тому

    Which editor is this ?

  • @ask4144
    @ask4144 4 роки тому +5

    I watched your video about the linked list
    I feel like a stack is just a kind of linked list

    • @JacobSorber
      @JacobSorber  4 роки тому +3

      A stack is an abstraction, that can be implemented using a linked list or an array, or as a block of memory and architecture and register-assisted pointer arithmetic (as is the case for your program's call stack). But, yes, when you implement it with a linked list, it feels like a linked list with some restrictions applied to it.

    • @ask4144
      @ask4144 4 роки тому

      @@JacobSorber thank you! I'm working on a project (sat solver) and this video is very helpful.

  • @frezajoe5836
    @frezajoe5836 2 роки тому +1

    is it possible to implement a stack with different type of data in it? like how routine call stacks works under the hood

    • @Thanos-hp1mw
      @Thanos-hp1mw Місяць тому

      We will need void pointers and unions for that I'm sure...

  • @milnueve89
    @milnueve89 3 роки тому

    Thanks for your instructive video!
    I'm self-taught, and I'm reading the book "The C Programming Language" by R&K.
    In this book on page 66, they implement a stack with an array for a Reverse Polish Calculator initialising the value of "top" at 0 instead of -1, actually "top" is named "sp" instead (stack position). So in push() you first push the value and then you increment "top", and in pop() you return the value with the index "top" decremented.
    The question is, wich alternative is most commonly used? In addition: Is one better than the other?
    I appreciate your time.
    Greetings!

    • @philperry6564
      @philperry6564 2 роки тому

      The implementation in the book is very good. Personally, I'd only use negative values, implicitly, for error handling but each his own. His pointer based implementation is probably the preferred/more efficient and flexible method.

    • @rustycherkas8229
      @rustycherkas8229 2 роки тому

      If you start the stack 'index' at 0, it conceptually hangs together with all that you know about arrays in C. The stack index tells you how many items are on the stack (like strlen() tells you how many chars are in an array) and where the next item pushed will go:
      int stack[ stackMax ], idx = 0;
      bool push( int val ) { if( idx == stackMax ) return false; stack[ idx++ ] = val; return true; }
      bool pop( int *val ) { if( idx == 0 ) return false; *val = stack[ --idx ]; return true; }
      Ideally, idx would be an unsigned integer type because it is a 'counting number'.
      You can have 2, 1 or 0 chickens, but you can't have -1 chicken...

  • @fabianmelo9672
    @fabianmelo9672 Рік тому +1

    Impressive how Matthew McConaughey knows about C

  • @cuongnguyenhuu1279
    @cuongnguyenhuu1279 4 роки тому

    Pls make video about implement tree and graph in C.

    • @JacobSorber
      @JacobSorber  4 роки тому

      It's on the list. If all goes well, you'll see it in the coming weeks.

  • @mohdzeeshan5287
    @mohdzeeshan5287 3 роки тому

    Hey .. can you make a video on 'tries' please?

    • @JacobSorber
      @JacobSorber  3 роки тому

      Yes, it's on my rather long list of future video topics. I'm not sure how long it will take me to get to it.

  • @mlfconv
    @mlfconv 3 роки тому

    What kind f editor do you use I though it was atom at first sight

  • @LinucNerd
    @LinucNerd 4 роки тому

    If you have a function that should return a value, but should also return a value if something went wrong, the best way I've found of distinguishing the return value from an error, is to just use pointers.
    If all is well, return a pointer to the value, else if something went wrong, return NULL.
    That may not always work, and so sometimes I've had to get a little tricky, and instead make the function itself write to an address if something went wrong, like so:
    int test(int *error) {
    // Sorry, tabs in comment section no work :(
    if (/* something went wrong */) {
    *error = 1;
    return 0;
    }
    return value; // Some normal value
    }
    After I watched this video, I was reminded or errno... Would it be wrong to use errno for these sorts of things? Or, what is the best way of dealing with this?

    • @JacobSorber
      @JacobSorber  4 роки тому +1

      If you were going to return a pointer, I would just malloc space for the result, and return the pointer. That way NULL, could be your error state, and anything else is a valid result.
      If you don't mind the extra time for a malloc call and the responsibility of eventually freeing it, then this is a really good way to go.
      I personally am not crazy about the errno approach. Global variables come with a lot of baggage-probably not going to work well with threads. I would specifically avoid errno, since it's used by a lot of other functions, and you could run into issues.
      You can also pass in a pointer to where you want to popped entry to go and return the success/failure as the return.
      Lots of options.

    • @RockTo11
      @RockTo11 4 роки тому

      Malloc would be slow. My advice would be to use an output parameter. Maybe something like:
      int stack_pop(int* success);
      int success;
      int result = stack_pop(&success);
      if (success == 0)
      printf("stack empty
      ");
      else
      printf("result: %d
      ", result);

  • @yagami-light
    @yagami-light 3 роки тому

    how do I make it work for any data type and not just int? please help me with this make a tutorial on using void pointers It would be really awesome please help

    • @JacobSorber
      @JacobSorber  3 роки тому +1

      A void pointer is just an integer, that happens to be interpreted by the compiler as a memory address. So, moving from int to void * should change almost nothing in the code.

    • @yagami-light
      @yagami-light 3 роки тому

      Thank You for Answering

  • @Stomachbuzz
    @Stomachbuzz 2 роки тому

    I don't quite understand you would create a stack manually?
    Isn't the stack something that the compiler creates to fit your code?
    I understand to explain the logic of the stack, but why am I doing the job of the compiler?

    • @JacobSorber
      @JacobSorber  2 роки тому +1

      Well, there is "THE STACK" meaning the call stack, and then there are stack data structures. The call stack is one stack and it is managed by the compiler. But, developers often use other stack data structures to manage various issues in their applications.

  • @bauglirmelkor5778
    @bauglirmelkor5778 2 роки тому

    doesn't "stack *mystack" is the same with" node **mystack" since stack type defined as "typedef node * stack;" why do we need pointer to pointer?

    • @newb_embedded040
      @newb_embedded040 Місяць тому

      To pass by reference in push and pop. Oherwise it won't update inside those function.

  • @EnjoyingBacon7
    @EnjoyingBacon7 2 роки тому

    What’s the point (at 8:46) of the temp node?he creates it, doesn’t use it, then frees it… I don’t get what it’s there for…

    • @rustycherkas8229
      @rustycherkas8229 2 роки тому

      tmp points to the 'head' node that is going to be free'd (temporarily hanging onto its address).
      The head pointer is changed (and aren't we glad we kept the old value?!)
      Now that the head pointer has been 'advanced', the node that WAS at the head is free'd.

  • @leocarvalho8051
    @leocarvalho8051 4 роки тому

    i did not get (*stack)->value . Why are you deferencing a pointer but then using the arrow thing???

    • @thebigmacd
      @thebigmacd 3 роки тому

      He's pointing to an item within the struct to which the pointer pointed.

    • @Thanos-hp1mw
      @Thanos-hp1mw Місяць тому

      Because stack is a pointer to a pointer. Meaning *stack is also a pointer.

  • @socat9311
    @socat9311 3 роки тому

    I did not get why pop cant return bool similar to push?

    • @JacobSorber
      @JacobSorber  3 роки тому +1

      pop is returning the thing that was removed from the stack. So, if pop returns bool, then you would need some other way to get the popped value back, maybe through a pointer passed in as an argument. You could do it that way, I was just trying to keep things simple.

    • @socat9311
      @socat9311 3 роки тому

      @@JacobSorber ah makes sense i thought it was more a "confirmation" function that says if the element was removed. Thanks!

  • @sumitbhosale3401
    @sumitbhosale3401 4 роки тому

    Also What is search.h in c programming.

    • @JacobSorber
      @JacobSorber  4 роки тому

      Header file for built-in hash table functionality. (XPG4.2 standard)

  • @marusdod3685
    @marusdod3685 4 роки тому +5

    you could use encapsulation by hiding some of the implementation in a c file

  • @peacemekka
    @peacemekka 3 роки тому +1

    I'm still scratching my head. Tutorial was good but I didn't really understand. I might have to practice.

    • @JacobSorber
      @JacobSorber  3 роки тому +1

      Practice is good, but feel free to ask about anything that's confusing.

    • @peacemekka
      @peacemekka 3 роки тому

      ​@@JacobSorber Okay so I tried the linked list one and I had trouble getting it. Then I went and wrote myself explanations for each line. And I think I get it somewhat now. Its not easy but atleast it makes sense. Will take me a few more goes before I understand properly.
      I suck at Data Structures. I slept through most ds classes throughout my semester. Regret it now.

  • @soniablanche5672
    @soniablanche5672 4 місяці тому

    how to implement a stack in javascript:
    const stack = [];

  • @no_name4796
    @no_name4796 Рік тому

    How to create a stack in c: use recursion in a smart way ;-)

    • @p99chan99
      @p99chan99 5 місяців тому

      Can you explain? kinda a newb at data structures but I never knew you could implement a stack using recursion

  • @magno5157
    @magno5157 3 роки тому

    I know you just want to show what a stack is. However, could you please not make examples using global variables? It encourages people who don't fully know all about global variables to use them. It's bad if they don't know there can be only one definition for each global variable anywhere in the program *unless* it has internal linkage (and even so there can be only one definition per translation unit). See, global variables are not that simple to people who don't understand linkages.

  • @tsunningwah3471
    @tsunningwah3471 3 місяці тому

    bbbbbbbbbbbbbb