C Programming In Windows | Daniel McCarthy | Skillshare
Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
44 Lessons (5h 2m)
    • 1. Introduction

    • 2. Installing The Compiler

    • 3. Creating A Hello World Program

    • 4. Variables

    • 5. Functions Explained

    • 6. Primitive Types

    • 7. Arrays

    • 8. Multidimensional Arrays

    • 9. Receiving Input From The Keyboard

    • 10. Pointers And Memory Addresses

    • 11. Function Pointers

    • 12. Structures And Structure Pointers

    • 13. Preprocessor

    • 14. Headers And Object Files

    • 15. If statements

    • 16. Operators

    • 17. Loops

    • 18. Legacy C

    • 19. Nesting Statements

    • 20. Global Variables And Positioning

    • 21. External Variables

    • 22. Null Terminators And Ascii Table

    • 23. Character Arrays Vs Character Pointers

    • 24. Typedefs

    • 25. Booleans Explained

    • 26. Unions

    • 27. Hex And Binary


    • 29. Automated Building With Makefiles

    • 30. Casting

    • 31. Creating Libraries

    • 32. Goto Keyword

    • 33. Memory Allocation And Stack Vs Heap

    • 34. Memory Functions

    • 35. Reading And Writing Files

    • 36. Const Explained

    • 37. Static Functions Explained

    • 38. Bitwise Operators And Bit Shifting

    • 39. Argc And Argv

    • 40. Seeking In Files

    • 41. Switches

    • 42. Simple Book Program Part 1

    • 43. Simple Book Program Part 2

    • 44. Simple Book Program Part 3

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class

It's time to finally master the C programming language. Dan your tutor has been developing in the C programming language for over ten years and has a lot of experience to give. What makes this course different than the others is that you will actually use the compiler an IDE will not do it for us we will be using the compiler ourselves this will give you the experience you need to manually use the GCC compiler. Be A Pro.

This course will teach you everything about the C programming language, you will be taken through the basics all the way to more complicated concepts such as functions pointers and library development.

We end this course by creating a book program that allows a user to create books, save them to disk and then read them again.

This course is beginner friendly regardless of your current skill level

What you’ll learn

  • How to know the C programming language very well
  • How to manually use the "gcc" C compiler
  • How to automate project building with "Makefiles"

Are there any course requirements or prerequisites?

  • Be able to follow the course all the way through, every lecture pushes you a little more further

Who this course is for:

  • C Programmers Who Want To Master The Language

Meet Your Teacher

Teacher Profile Image

Daniel McCarthy

There is always more to learn


Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Your creative journey starts here.

  • Unlimited access to every class
  • Supportive online creative community
  • Learn offline with Skillshare’s app

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.



1. Introduction: Hey, and welcome in this course, you're gonna learn how to program. See in Windows. I have 10 years experience in the C programming language. You're learning from an expert. We're going to start with all the beginner stuff, variables, functions, and then we'll move too much more complicate concepts such as Pointers function, Pointers and the pre process er. We also end the course by creating our own little book program that allows you toe load books and write books to disk a fantastic course. I'm sure you'll love it. 2. Installing The Compiler: Hello and welcome everybody. And in this lecture we are going to install Visual Studio Code and MNC Gu. So the first thing I want you to do is I wanted to go to dragons app.com forward slash downloads and then just click C programming and windows on the left here. If you still can't find it, just go to dragons app.com, scroll all the way down and you'll see downloads here and just click that. Now the first thing we're gonna do is we're going to install Visual Studio code. So just press Visual Studio Code download. And we're on Windows. Just select the Windows here. Save the file, run it, and we're just gonna go through this installer. Now Visual Studio Code is essentially a code editor, okay? So you can just press Next, Next, Next, make sure that the path is set. Just go next, Install. And then we just let that complete. So we're now going to press launch Visual Studio Code and press Finish. Okay, I am, this is Visual Studio Code, so that's all installed correctly. Brilliant. Close out of that, I'm pressed the browser back button just to take us back to the download page here. And now we're going to press Ming. Good download. Now you have to wait a few seconds while this downloads here. Well, while it prompts us for the download, and I'll just press Save File. And we're going to run that installer. And we're just gonna go next. And keep all the settings the same. Yours might be higher than mine. That should be okay because C, C maintains backwards compatibility. So if you're watching this two years from now and it says version ten or something. Don't worry about it, Just press Next and you'll see destination folder. That's completely fine next. So now you just have to wait. This can take like five minutes. I have an SSD disk. So it's five minutes for me. For you, it might be maybe 10, 20 minutes. So you might want to pause the video here. So once the install nations complete, just press Next. It'll tell you it's completed. And if we now open CMD command prompt and we type gcc, you will see that it says GCC is not recognized as an internal, external command. Now GCC compiler. Now the reason that, the reason it says this is because we need to set up environment variables, okay, and once we've done that, it will resolve that successfully. So to resolve this resolution problem, just go into I'll C drive Program Files, Ming Gu, W6, fall. Double-click that directory there. And then you'll see mingled 32, double-click Ming Bu 32, and then double-click been. And here you will see GCC, GCC dot EXE. So just copy the path by here. Okay? And we're gonna go to the environment variables. So just search for E EN and then edit the system environment variables. Click environment variables here. And you'll see path just by here. Press Edit, press New Control V, that path. Press Okay. Go back to environment variables because we also want to add it to our local account. So a here, a here, use the variables fall Dan's be, that'll be your name. Go to path and press Edit. Press New Control V to paste that in. Okay. Okay. Okay. Now close command prompt, reopen command prompt, GCC, and we can see GCC fatal error, no input files that resolves that resolution issue. So we've now got the compiler completely set up. And on the next lecture now we will be able to start coding C. Thanks for watching. 3. Creating A Hello World Program: Okay. Welcome back, guys. We're going to create a hello will program now, which is just be a simple program written and see that I puts the message. Hello, world. Very, very simple. So let's open up visual codes that you installed. Make sure you don't accidently press visual studio if that's what you have. Um, visual studio code is what the one we should be opening. Um, and you'll see that you'll see that this old nice and open now. And we're going to create a new folder on our desktops. Open up your browser here. Your file browser. We're just gonna call it. Hello, world. Hello, world. Make sure there's no spaces. Um, right, Cool. So in here, back of visual code. Go open folder file Open folder. Select your desktop. Hello, Wilder and I should load it. Excellent. So you'll see this new fall button by here. Hello, World up. New fall. Just click it on. We're gonna call it main dot c. Okay. And then it's gonna ask you down here. We recommend you install this extension press and stole because that that that will actually help us when writing our C code and if it didn't give you that. By the way, just collect a little plug INS thing down here the extensions and just search for C, C or C plus plus as just or something to help you a little bit more. So that is now done that. So what I want you to do is is I want you to include a head of foul on head of falls in sea are basically files that contain loads of definitions on and function prototypes. But more on that later. Just copy what I'm doing. So we're going to go hashtag include and then we're going to go STD ioo dot h. So it should look like that. Include left arrow, STD I oda page right arrow. So that will give us access to some printing functions. Some functions that allow us to print messages out to the users. No, actually, print on your home printer output message to the user. Basically, it contains that a lot of you, a lot of functions that allow us to handle user output on important and so So what I want you to do now is go in Georgia Maine bracket insta oxy shar RV. I make she copied me. Exactly. Guys. So you can see this is a common there as well. Don't forget anything. Um, so I'm briefly going to go over this now, but you will know more about it later on as we go through the tutorial. So, um, as I explained, STD ioo dot pages of file. Ah, that contains prototypes. Two functions that we can use to output messages to the user. So that's a bit of a mouthful. But I have to worry. We'll explain that much more later on. So this is a function called main on the main function is basically executed whenever you start your program. So anything in between anything by here will be run when you when you run in your program. Basically. Now, this function contains two arguments oxi an R V. Now, using these two together can allow us to access data, uh, that the user can pass to us when, when loading our program. So that briefly explains that. But you don't need to worry too much about that yet because this is the very first tutorial . So what are you doing in between these brackets is I just wanted to return zero. Now, what this is going to do is this functional Gavron. And then we just returned zero back to the operating system because the operating system calls this function for us, right? If you return anything other than zero, anything other than zero it is classed as an error. Um, only if you returning it from the main function, though, right? What'll happen is on the command, prompt or terminal. If you're in linen, it'll tell you, um, code returned on. It will be what you returned here. So So this allows you to return states to the back to the calling program, the program that's just running you so returning zero generally means everything went okay . Returning some negatives usually eat era. But, you know, even returning some positive can be an error. Usually it's a negative value if there's a problem Anyway, back to the story. So once you don't return zero, that means that we're basically saying everything grand. Fine. It's just something We're returning to the caller, but we need toe output, our hello world. So go into here and type print F hello World explanation rock and put a semi colon at the end here. So you should see this is your program now on. It's very simple outputs hello world and then returns. Now, if you didn't have this, the program would still compile. But it would return whatever was on the stack at that time, which you can basically assume that it's undefined behavior. So you shouldn't should always return something when the type he's not avoid type. But we'll we'll explain more about what voyages and interject later on. That's just something to remember, in case you know a little bit about that already. Now go back to your file. Explorer on. Go to your directory. Go to the directory that you created your Aperol minds on the desktop on. All I want is you want to copy the your L Appear on. We're gonna go here. We're gonna type command prompt while you do CD. I just wanted to right click and it should pasted in automatically on just press enter on. Well, how did that change the working directory to To our hello world ac? And now we're going to go gcc dot forward slash main dot c space Dachau dot forward slash Maine and just press enter on Now you can see if you go back to the directory. It's curated a foul called main dot dxc. So we've basically now just compiled our program. So GCC is the compiler We pass in our input file, which is main dot c and then we use dash O to say that we're about to output the compiled file. This is where we wanted output to, and we use stopped forward slash Ming and Doc Ford, slash main is our output file. So it takes main dot c, which is our program we just wrote here. It compiles it into machine code on symbols and, um, dynamic basically object files on. Then it creates an excusable called main. On On on Lennix you'll actually see main, but on windows it depends the dot e x e at the end the compiler does so if we now do dot forward slash main door e x e. By the way, doc, forward slash means this directory in case you didn't know. So when we do doc forward slash it means it means in this case, it means inside the hello World app directory. Anyways to do Doc ford slash main Dottie XY and press enter on. You see, it complained. Celeski better. That's just your main Dottie xy Andi, It will say hello, world. So congratulations. You've just written your very first see programme. I'm sure you're pretty confused right now, especially with some of the terms are being talking about. But you really not need to worry because this is our very first lecture on was designed to just give you a taste of the pudding. Essentially, eso all of this will be explained. Um, it in further in depth will explain what thes thes types are. Will explain how to correct functions will explain what these two asterisks mean. You know, things like that which is probably confusing you right now. So there's really nothing to worry about. Keep following course on all will be revealed. So yeah, congratulations on creating your very first see program. Good job. 4. Variables: Hello, guys. I'm gonna explain more variables are now in si Variables are basically places where you can put values and basically store information in memory. So, for example, if we did inter X equals 50 then this would store the value 50 in the X bearable on if we did. I don't know, um, in Georgia y equals 20. Then we start 20 in the UAE variable and then these guests stored in memory and you can access them later. So thes are basically the data types of your bearable Essentially that the type of information you'll be storing so more on that later. But I'll briefly describe it. Now I nt is an interest. You're basically that can hold numbers. So that's all that that means on Dhere is our variable name, so we'll use the name to access it later on. Essentially, variables are defined with names so that they could be referenced throughout your program. 5. Functions Explained: Welcome back, guys. So now we're gonna actually learn how to correct functions. And I got explain functions a little more because I think I think is more important to learn about functions before I teach you about data types such as intra Jurin shar functions. That kind of required first. Really? So what I'm gonna do, I want you to copy what I'm doing. We're gonna go avoid my fun Avoid. Okay, so let's explain this. My funk is a function dysfunction doesn't take any function arguments. So we put void in here. Now what you can do if you go back into Maine, I can I can call my funk like this. And what will happen is our program. When it goes into the main function, it will call my funk, which will start running code in here. So if I went in here and I did printer my funk cold and put a semi colon at the end because in See you and all lines of code with a semi column, everything between these brackets here is the code that gets run when you call the function . So obviously this is the name. This is the return type on inside. Here goes the function Arguments now avoid return type means we're not returning any value . That's what this means. So when you call my funk on the return type is void. Nothing is returned, so there's no need tohave return. There's no need to have this. But if you did want to use the return key word to return from my funk earlier than you could, you would just go return like this. There's no need to pass in a value or anything like that because it's of avoid return type , which means no values returned. And if I was to have a print here, you don't have to do this. Just an example. This would never be called because we print out my funk cold and then we return from the function so that print F test never gets called on. There are reasons for when you would use this, such as returning from a function early based on a condition of some kind. Okay, if we now go back to command, prompt Andi once again you need to go to the hello Will APP directory and we opened up cmd for command prompt. We type CD, right click to paste Press enter, and now we can compile a program again. So just to GCC main dot C, Dachau Main Press Center, our programs now compiled on Now, if you type main and press enter, you can see my funk called Hello World on. You'll notice that they're all in the same line. What if you wanted a separate line? While there's a special way to do that and see you just do this So this character here means that you're gonna use some sort of special character code of some kind. So by doing this and end, that means new line, whereas if you did, uh, instead of en that is a carriage return, so quite commonly you'll see RN so character turn and then a new line, but and would just be fine for now. It's fine in most cases, so if you do the same here and we go back up, press Thea power twice to come back to your compile command press. Enter GCC compiler were now run and then do main, and we can see there now on separate lines. So that's how you create new lines in and see use this. So let me explain another thing that we can do. Let's make a new function. It's going to return an intra Asia, which is a number, by the way. Interest sure is a number. Andi, we're going to call it my son on. We're gonna have an argument here in Georgia A. And another argument in should you be So while this will do, the's will add them both together and return the result. So how do we do that? Well, you do return a plus B. So just like mathematics on a calculator where you might do 20 plus 30. Here we do a plus B. So what will happen is one someone calls my son. They pass in Ah, value here on a value here. And then it gets added together and ever turns the result. So let's now Garrett of this line here, my funk, and we're going to go My son five and five. So what this does five goes into a as we did here. And then this five goes in to be just a simple pious I'm gonna changes to attend to explain this a little better. So 10 goes into a five goes into B and have our works. Is it? Lying Is in line with these arguments. That's how it works. So we can see my some takes an intra jet. So he passed in 10 and it also takes another interject. So we passed him five. Now we can see we're not storing this result anywhere. So let's now store that results. So if we go in Georgia, result equals my son. 10 5 Now, what have we done? We have created a variable. Now, variables and see allow you to store information. Uh, so in our case, we've created a variable called Result on result Will store a number now. Decimal points cannot be in intra GIs. You use doubles for that or floats, but that will be explained more later. Now, if we now run that program, nothing would happen because it would something together. But we don't have put the result. So how do we do that? Well, let me show you. Let's give it to this. We're gonna go print f result equals. No result is I'm gonna do Result is so so you don't get confused thinking that the equals is required result is on you do? I percent I and then you do the new line. So what happens here then? Well, currently undefined behaviour. Because we haven't defined the result. We haven't supplied the result. But what will happen is it will say the result is on in percent. I takes from an argument that we provide here. So if we do result, we press control less to save. So it says result equals my some 10 5 which calls dysfunction. We add A and B together, which is in our cases 10 and five. The result is returned and stored in the result variable which is an interject a number and then we output the result by saying result is percent I now one that one the one the program sees percent I it looks for these arguments passed to us here on they have to be provided in line with Thea arguments provided So for example, if we just change, it's a little bit more I want you to do instead of result is we're gonna give it to this now because I just need to explain that to you. So we're going to say I plus I equals I now here we provide 10 and here we provide five. And what this will do is the operating system comes in. It runs our program. It sees percent I. So then we pull from the first argument here, which is 10. And then we output a plus symbol. Literally, this could be this could even be plus just to show that they're unrelated. And then it finds another percent I and it puts five in there. And then finally it outputs an equal sign and then it has a percent I again and it outputs the result. So if we compile that now, go back to the program up it twice. Enter a pit once or twice. May 10 plus five equals 15. So that's how the functions work. So essentially you defying a return type, Which is this you to find a function name, which is that and you define arguments in between these brackets? Everything between these curly braces is the code that's run when this function is called. So you can think of functions as ways of splitting up our program into different pieces. They're an essential part, ISI, and they're very important on they allow you to prevent repeating yourself in code, which is a very important thing for a clean code base. So that is how you define functions. But let's explain a little more now. What happens if main is at the top? Well, there'll be a compiler era if you go back here when that again implicate declaration of function my some Okay, why is that, then? Well, because these are the fine below. So when the compiler comes in and it goes toe call my son, my son hasn't doesn't exist yet because that the compiler hasn't seen it yet because it's below it. So how did you get around that problem? Well, you define what's known as a prototype. If you if you copy this line here, paste it here. I just put a semi colon at the end. So what this now says is that says to the compiler, This is a prototype for my son. This is what it will look like. I will define it later. I don't really care about right now, but you need to be aware of it for later. That's what this says Now if we go to compile it now, you can see it compiles. Fine, because we've let the compile in. No, that we will be declaring this later on. Now, this is how the head of faults work. So these function prototypes exist in the head of fouls. So the one you include this it will have a bunch of these for print. If it will be like that, for example, Andi, when we call print F hasn't It doesn't. Actually, it's not defined like this with Curley's, and everything is just a prototype like this, which basically means this exists somewhere. We don't know where it exists yet, but just make a note of it because we're gonna be using it. That's all the prototypes do on again, a very important part of C. So that is function prototypes. 6. Primitive Types: hello and welcome back. So I'm now gonna learn about primitive, primitive types in see. So what are primitive types, while primitive types are the data types built into the language itself, so intrigued. Your is a primitive type that allows us to store numbers or return numbers. Shar is for characters such as A or B or C, for example, a single character. So let's first discuss what void is, as you know, already based on previous lectures. Avoid is a data type that means we will return no value. Basically, it's like it is avoid, you know, you think of a void in real life. It's nothing, right? So fast pass avoid basically, is it avoid basically represents that there is no number or no data of any kind. That's basically what void means. But pointers are a little different, and we'll explain that. Another lecture. Okay, so next we have char. So what is it? Shot Charles allow you to store characters so I could do something like this. For example, Andi Charles R. Eight bits in length or one bite eso, obviously in seed, depending the data type you should use should depend on how much data you need to store on what it's being used for. So typically numbers you would use an intra job. In most cases, you would even prefer an insurgent over a char, even if the numbers could fit into the chart data type, which is a which is one bite. Eight bits. Now what can eight bits store eight bits can store Children 55 number up to 255 if it is unsigned. But we will explain the difference between signed and unsigned shortly now. So use child when you want to store characters. Next you have Oh yeah, Another thing. These quotes by here allow us to define a single A single bite as a character. So this is converted into the decimal equivalent based on the asking table. So Teoh short next. So short is a number just like injured here, but it can store a lot less. Short is for numbers that can't store as many bikes is introgen. If you need to store, um, numbers that are much larger, like above above like 70,050 60,000 onwards, then your best years. An intra jer on and sign short will explain the signs soon enough. However, on unsigned Short cannot store more than 65,535 uh, as a number, so office. If you want to go higher than that, you need to use an inch here, guys. So then intra jurors, you know, is a data type that can store about four billion. Ah, number 24 billion something. But the number can only be around four billion if it's unsigned. If it's signed the numbers about two billion. So if you need to go higher than that, you should use a long on. A Long is a huge number. It is eight bytes in length. Andi ITC Unstoppable. A huge, huge number. I can't even tell you what the number is because it's so big. Um, so you use a long way where you deal with things that are much, much larger when you deal with numbers that extremely large, so quick Overview, then Schaars are one bite in length. Shorts are two bytes in length. Um, introduce our four bytes in length on Longs at eight bytes in length, but that assumes you're using a modern process. Er, if you can policy on embedded or or on older systems than these data types. Sizes will will be different lengths. So make sure you read about that. That's why it's hard for me to tell you exactly how much they stole because it really depends on the architecture. If if you're working on a Windows machine or something, then what I've told you is accurate. If you're working on on embedded process or something, or a really old machine than than these beasts the size of these are our show are smaller in length. Okay, so then we have float. Now afloat is basically, um, a number that the way you can store decimals. So, for example, and you're Sopron Eupen effort The end of literal numbers. When you actually enter the number, you put an effort the end to represent float usually as well. So floats a great for storing things like currency, for example, like pounds and pence dollars and sent. Um, now double is a large, um, floating point number. So you So again you can store deaths. You can store currencies, stuff like that. But double is much bigger than float. The same as long is much bigger than introgen Okay, so you would use a double for large numbers that that a decimal place and you use afloat for smaller numbers than a decimal place. But double is your best use double if you're doing the currency. Um, so that is the primitive types Charles Shaw inst your long float double. Okay, so now let's explain. Unsigned versus signed. So unsigned is represented by this unsigned key would. So all all primitive types can have an unsigned just before the data types defines. So you can have unsigned long. You can have unsigned integer on. What this basically does is it means it can't go negative. Um, unsigned numbers allow a data type toehold mawr in the positive range, but you can't store in the negative range. So by default, any data type define is by default Signed. So, for example, if I give it a rest a second, So, for example, signed in it MM equals 30 is equivalent to interject him. So signed is basically invisible. It's it's always there unless you define unsigned, right, so assigned Congar negative on positive so it could be minus 50 or it can be 50. It can also be zero now unsigned can only be 50 and zero. You can't go negative. If you try to go negative on the signed Introgen or unsigned anything, it'll loop back around eso. Essentially, it will become the highest number possible for that data type. And that's what happens when you exceed the maximum boundaries and see they look back around. So that's very important to know that, um, so the The difference here, then, is if you want a positive number, but you don't care about negative, you can use unsigned, but if you need negative as well, then signed is best. But unless you're working with much larger numbers, you won't have to worry about Sign itch too much. If you are defining some sort of file format, then obviously you need to take more care whether you signed or unsigned things, but essentially use unsigned if you need to. Andi, if you won't have negative numbers, because that's very important to note that on the data type you choose will depend exactly on how much data you're gonna be storing Andi on circumstance. If you're storing in a file, for example on, you know that like, for example, doing using inched. You're here. Even though you're only work with low numbers, it's not so bad. But if you're working, if you're gonna be working with files where store where the man you store is pretty crucial , then you should be more careful. So, for example, if I if I know that my number won't be above 255 and will always be above minus one, in other words, it won't be negative. Then it makes sense to use an unsigned sharp because if I use a chart, what happens is it becomes signed, which means that I can have negative. I think it's negative. 127 and then on M plus 127 right? But if I use unsigned, then I can only have up to 255 positive, but by senators unsigned. Extend the map data Aiken store in there. But I can't have negative numbers. So using that, I can have in the negative range and the positive range. But I basically lose half of the positives potential length because I need Teoh take into account that I could have negative numbers. You one sign it, then you use the full amount of bites, basically extending the number you can store in that amount of bites that sharper vice, which is one bite. You sign it, you have the negative range, but you lose some of the positive range. So they're important things to note very important things to note. Now that is data types. I hope that makes sense, because if it doesn't send me a message and I'll make follow video but essentially unsigned and signed concepts you should know. 7. Arrays: Welcome back, guys. So now we're gonna learn about a raise. So what is an array? Honore allows you to define a variable with a given name, but have it so it can install multiple of the same type. So it's best I show you this in code so you can see it clearly. Let's say I wanted to take a name at some point in time from my user. Well, what I would do is I would create a character array for the name and in here goes the length. So Sean Nane 20 with these brackets as well. So what that means is a name variable that has a type of char, so it can only store one bite at a time. Onda, we wanted toe have 20 bites. So in other words, weaken store 20 bites in this name Variable. So how does that work then? If char can only stole one bite? What happens is the compiler looks of the data type. It seizes the shar so noses one bite Then it sees this number on it knows that we want to have 20 of them on it also knows we want it to be able to be referenced by the same name since Charney. So it allows us to access 20 bytes using the same name. So how do you access them, then? Well, like this. Let's say we wanted to set name to a like we did in previous tutorials. You can see a sank ticks era. Why? Because this is an array we can't defend. We can't said it like this. So if we didn't name zero equals a that works. Fine. So what's happened here, then, is we set the first bites and I'm name array to zero, because in C indexes start from zero and you access indexes in a race. So in this case, what we're doing, we're accessing index zero from the name array. On was setting it to a You know, you could do the same here. One equals p name to equal c. And now, if you wanted to output that you could go print f s. I mean, see? So see, forget for char. And then we go. Here we go. Name zero. So what? That'll do, they'll open a If we put a one here, it would output b, we put a to here. Would I put C. Now there's rules for these indexes. Firstly, they can't be negative. Secondly, indexes always start from zero. In other words, if I wanted to access bite one of this name array, I would you zero. The third rule is always in the fourth. You cannot exceed this length. Say I want to access the last bite of this A rape. Would I do name 20? Absolutely not. I would do name 19 because they start from zero when we access it. We always start from zero. So name 19 equals D would set the last bite of this array to D. Now, in most languages, like Java and stuff like that, if you exceed the buffer, the buffet is another word for a raid. By the way, if you exceed it, what will happen is it will throw some sort of exception on your program, will gracefully end in. See it doesn't work like that in. See if you exceed this buffer. At best case scenario, your program will crash. Worst case scenario Hacker could use this to their advantage on it. Really. Is that serious? Because in si, when one it's compiled, there's a bunch of return addresses on stuff like that stored on the stack. I'm right now. We saw this array on the stack. Um, how stack works is when you enter a function, then allocates some room on the stack. Uh, for ALS, the bites that in this scope on the scope is anything between these brackets, that's what a scope it's. So in our case, it will allocate 20 bites on the stack for us. And they will also allocate some bites for these variables here for our function Prototype . Now, the stack memory is allocated by simply debt decree menting the base point or stack pointer . Andi, the problem with that is is you can also run out of space very easily because we're not asking the operating system for Teoh. Give us some some data here. We're not doing that. What we're doing is we already have the data and we're just literally just moving the point of down 24 28 bites on. That's what would do him on then. That gives us room to set these things. So what happens is when you leave the function, it resets the pointer back to where it waas on. Now once it once it does that everything here gets naturally freed on When I say freed, I don't mean deleted. It just kind of like it kind of It ends up in a kind of like, um, undefined state, and it can be overridden by other function calls and stuff like that. But you don't need a way too much about that. That's very quite complicated subject. But the point is I'm trying to make is you have to be careful how much you allocate on the stack, because the stack can only take so much on secondly, back to our potential problem where if you go over this buffer and experienced hacker could offset this just right to overwrite the return address that will be on the stack. And while the return address does is it basically holds the address to the last function that called you? So then one this function finishes. It will pull that address and go back to where was executed. On the problem with that is a hacker experienced hacker could overflow this buffer. It's called a buffer overflow. You're welcome to look it up, and when they overflow it, they could override that address to point to somewhere else. And that's why it's very dangerous. Um, so in. See, you always have to make sure you check that. Anything you're accessing here can fit. So, for example, let's say I had an integer I equals 50 and I did name I equals E. So what will happen is it would set it would go into I will pull 50 on it would set index 50. But the problem here is we can only store 20 bites. So what happens is it'll crash the program. But experience hacker could change that on do nasty things. So how you get around that is you ca nbae sickly check that I can fit into here on If it can't, Then you don't set it Behm or two conditions later on. Just wanted to get that out there. So what? What? What we can do now, then, is we contest this so give it. Did not name 19 If you did that does not oppress the program. Right on. We're gonna open up command. Prompt CMD Andi, I'm going. Teoh, Copy and paste this address by going CD. We're going to right click in tow. And now you're gonna go GCC main dot c. Dachau main on that shit. Compile. Fine. Do may now and you can see that output. See, because we're out putting element to in the array, which is C So that's how raise work it allows you to access, um, the same variable name on multiple bites. So that's that's literally all it is. So, basically, rather than having 20 different variables named name one name tuning three named, forming five, you can just do name and then do 20 on it. Really is that simple, And it's very efficient as well. But you can access the's in any in a number of different ways. Like such as using loops. There's without a raise. The language wouldn't really work very well. So that's what a razor, Andi. Basically, that is. That is it for a race, you can have a raise of all different types. I could have an interest. You're a for example, Insta ABC 30. So now I have declared 30 inches and I could go. A B C zero equals 55 ABC one. He was 22. So that is what a raise up. A very, very handy feature of the language, and you can see why 8. Multidimensional Arrays: Okay, guys, I now want to show you what multi dimensional a razor now multi dimensional raise a really good feature. Let me try and explain it in a way you'll understand. You know, like tile games like towel based games such as, for example, mine sweeper. They're uplift example of when you could use a multi dimensional array. So, for example, let's do this. Go charm at 20 20 that's a multi dimensional array, so we define a variable that is named map. It's an array that holds a raise, so it holds 20 arrays that contain 20 bites. So this allows us to do things like this map 00 equals 50 on. You know, it's how we don't have to pile pass this. The reason for that is because all of this does is convert said into its Mu Emmerich type based on the asking table, which you should definitely look up. So a, I think is decimal 65 anyway. So you know you can do literally do things like this, and that is what multi dimensional a razor. So you know, it might be map. Why x for coordinates and you would have a Y variable an experiment you would define somewhere. Appear, for example, and you can also defying variables like this, by the way, on the same line. So we define two variables, one called Y one called X, and they're both equal to 30. So, yeah, that's multi dimensional arrays, and this could go on forever. We can even have 1/3 dimension or fourth, Um, you can keep adding to it. So that's multi dimensional arrays for you, very much like a raise, apart from their multi dimensional where which means they're great for things like coordinate systems. You know, two of these could be used to represent X and Y values X and Y coordinates, so that's multi dimensional raise for you. 9. Receiving Input From The Keyboard: so, up until this video, we have done mostly theory. But I needed to do that to bring you up to speed guys. So now what we're gonna do is we're gonna make a program that takes someone's name and age and outputs it to them. So it's a pretty simple program. So the first thing we need we need to make some room, make some space. So let's define a name array that takes 20 bites. So this will take their full name on little, store it into this name Marie. And what we're gonna do is we're gonna go scan F percent s, which means we are wanting to read a string, and then we just provide name here. So while this will do is scan F reads from the keyboard, right percent s means were reading a string, and then name is the variable. We want to actually input that data into now. What happens when you put name here is it will take the address, the memory address of our array, and it'll pass it to the scanner function. That's what's happening here. And you can also pass the dresses by putting in M percent by their but for a raise without the am present automatically does that for normal variables on a raise, you have to use an percent. Here goes so down here. Then I want you to go print F percent s and just before that go, your name is percent s. And in the next argument, we just passed the name and also do a new lying as well at the end. So this should be pretty straightforward to understand. We read in the name using scan. If the system knows we want to read in a string because we use percent s on the string is basically, you know, syriza characters sis can f will re from the keyboard and anything we import, it will store into our name Marie and then we output. Your name is percent s and we pass in the name so it will give a sunning to us. So you go back to the terminal that makes you've see deed into your directory and we're going to go up twice. Enter and then we're gonna go main enter. I know nothing happens because it's what is waiting for us to enter our names. So I'm just going to Dan. Press enter and it says your name is done. Not bad, Not bad at all. So what we can do here, then, is we can say we can now read and then their age. So just up here, if you go insta, age equals zero and you do SCANA percent I for interject and then we do age on this won't work. Make sure there's an percent Here goes so you don't run into problems because we're getting the address of the age variable on passing it scan. If so, what happens is all our variables have memory addresses. So by using M percent, we're passing the address to scan F. So so scan F knows where to store our number that we enter. So then it say so then down here, do another print. Af your age is percent high on then in the second idea passing age and again use an percent here, guys, because we want to read in the address, go back to the terminal running a program two main again. Now answer your name. Enter your age. Oh yeah. In this case, we shouldn't have used the n percent because we are out putting a literal value. Whereas here, we need to use the AmBisome because scan f expects somewhere to store it here. We don't need to know the address. We just need to know the value. So that was my mistake. Go back in Nepal again on run main into your name. Done. Your name is Dan. Your age is 24. So then, you know, if you want to be cool about you can say on in 10 years, you will be percent I And then here you can go age plus 10. So now if we do that again and we run May Dan, your age is 30 and in 10 years you'll be 40. So yeah, pretty simple stuff. So just to demonstrate this, then if we went to provide the m percent and we try to compile that compiles fine, But if we run it and now type Dan and type your type your age. What's this? What's happened? It crashed. The program crashed on this because you need the n percent. Because if we just provide age is the equivalent to passing in this zero. So it's saying to the cysts, because age is equal to zero, right? So it's the equivalent of saying, um, reads in an age and store story in address zero. But address zero is no our age bearable. And that's the problem, right? So you need to provide the and percent and I'll explain more in the next lecture about memory addresses. Okay, guys, this some of stuff. I want to just go over quickly. So you notice we provide an M percent of age, but not for name. The reason for this is because a raise you don't have to provide the n percent. If you just provide the the actual variable name of an array, it'll automatically take the Empress in lots of money. Take the address automatically, whereas for normal variables, the ampersand is required because otherwise it will take its normal value. So that clears that up. Okay. Secondly, thing I want to second thing I want to discuss is, if you run the program again, you type full name, you will see you just re compile that a minute. You will see that it doesn't work. It just says your name's Paul. The reason for that is because scan f stops of the nearest white space. In other words, a space or a. Now that's something that's a white space, right? So there's another issue with this code we don't actually check. If the data were reading fits in the bounds of the array. Remember what I was saying earlier? That it's very important. So because of that, it means that we can enter a really large name that's above 20 bites, and it might not even crash the program. It doesn't always does, but that doesn't mean it's right. If it doesn't crash the program, chances are you've corrupted some data, but it hasn't led to a crash. Have I just do that? And you can see it crashed the program that time now because we've exceeded the 20 bytes restored this, which is way more than 20 bites. So what's happened is it's gone over. The 20 bytes is probably over, wrote our age variable. Or maybe these ones, depending on the order that the compiler compiled them into the binary fall and because it's over, wrote those values. It's actually led to a crash because we've probably over written the return address or something. Now, remember, I was saying hackers can exploit this to nasty things. So I'm gonna show you in one line of code how to fix first this problem where only alleged to enter first name because it sees the space and then stops on. Secondly, the second problem where it overflows the buffet. So we're gonna fix all of that one line of code. Now, the function to use to do this is called F gets f gets reads from a file. Now I know what you're thinking. Well, this isn't a file, right, Well in, see, you have what's known as STD in on STD out. Now, both of these things are file pointers. They can be used as if they were a file on disk, even though they're not. So STD in contains any input that we passed through our program While it's running, STD out contains any data without putting Okay, so that makes sense now less scared of our scan. If name here and we're gonna do f gets that's gonna ask for a buffet, says passing name on. Remember, you don't have to pass a 9% here because a raise, they automatically put the address when you referenced them by name, whereas normal variables. You need to provide the n percent to say this is an address. Now we go here. It asked for a Max count. So just to size of name, which will be 20 bites right So size off gets the size of the name variable, which is 20 bytes and asked for a file stream. Just type STD in. And now if we can pull that now and we run that, you can say Polo Brian, age 90. And it'll say your name is Paul O Brien, Your ages 90 and in 10 years you'll be 100 now. Type loads is rubbish. Again, let's overflow the buffer. What happens? It doesn't work. It stops us. It only it only allows us to enter a name of 20 bites. So it stops. It stops putting more data into the array when we reach that 20 bite cap. So I hope that sums up a lot of this stuff for you guys. 10. Pointers And Memory Addresses: Hello, guys. And welcome back. We're now gonna learn about memory addresses and pointers. So firstly, know that everything in C has a memory address. Functions have memory addresses, variables have memory addresses. Literally. Everything has memory address once it's compiled, um, so we can access those memory addresses to do really cool things. So, for example, uh, I can access the memory address of Oxy here on change it anywhere in my program. Um, I could access the memory address of a function. Andi be able to call that function even without knowing the function name to begin with, but we can get on that later. Let's now start memory addresses and pointers. So firstly, do do you print f percent p for pointer? And we're just output in the memory address right now of Oxy. That's all. I want you to Dongo, Ampersand, oxi. And then obviously we do your command prompt. We're going to see d into our hello world app again. We're gonna go gcc main dot c Dachau main and then we're gonna do main. You can see outputs the this this Hexi decimal number here. So this is the memory address that Oxy is at when you load this program on Oxy is a stack variable, which means that it gets deleted when we leave this function on. That's important to note because it means if I share this this address around the program, ah, as soon as I leave this scope that addresses now dangerous and you shouldn't be accessing it. So that's important to note. Um, stack stack data should only be access when it's safe to do so. So, in other words, if this function main calls another function that calls another function the cause, another function and so on this address conceivably be accessed. But if I stole the address foxy somewhere globally, and then I leave this function the second I leave this function that dresses now unsafe, we can't access that address anymore because the stack point to remember I was sitting with Stack Pointer. It gets pushed back up the base point of SEC Point that they get pushed back up on then that that that data is no longer accessible, but you can access it is unsafe to do so right, So that briefly explains that. So, essentially, if we do print F, let's do less to instruct a equals 50 and then we go print f I'm just gonna do I for both of these that this time rather than p just to demonstrate this so you can see we output the address as an interview on We have put the value of a says Compile that again So you can see when we use the ampersand it gives us the address as a decimal on. That's the memory address of a on Then we don't put the n percent so outputs the value of a So I hope that shows that by using the am profess m percent, you can get the address of things. Okay, so now point is, let me explain. Pointed to you This is very, very important parts. And I remember I said, start when we first started this course I mentioned I'll tell you what he's asked. Risks mean while their point is eso let me explain that to them. If you do in Chioggia asterisk p just for point of that's available name by the way equals percent a. Now what we've done here, we've created a point of arable on point of variables, basically introduced the whole memory addresses and we've created a point of arable. The points to the address of a on Remember, Remember, earlier we were testing output in the memory address on the value. So remember, in this case, then you know this memory address would go into p right on. Because we know the memory address, we can overwrite the memory address essentially overriding variable A says called Appointed and obviously pointers have data types. So in my case, Introgen. So it means that when I access this this, uh, memory address, it will be treating it as an interview. And that's why the state of types pretty important here. So I will need you to do, uh, ask Chris P equals 20. So what does that to them? Well, without the ask Chris, we just change the value of the pointer on. Remember, the value of the pointer is the memory address toe what it's pointing at in our case and percent a or the address of eight. Now, when you put ask risk before the p by here you're saying No, no, no, Don't set the memory address. Don't don't set the value of p set the value that p is pointing to That is what you're saying. So once again, without the ask risk set the value of our point of arable to address 20 with the asterisk set, the set the value that P is pointing to 2 20 on our cases, pointing to available eight. So guess will happen. A will become 20 I just to demonstrate this. I want to do print f I backslash end for new line. No, not required. But you can get passing a death so this will output the value of a which is 50. But we change it here to 20 with our point of arable. So if you go back now and compile that, run that again, you can see 20 output it so you can see that we've successfully changed the value of a by using a point of bearable. And now to explain R V when you have two asks asterisks instead of one. What you're saying is you are creating a pointer of pointers. That is basically what you're saying. Okay, so now I want to show you something else. You can access a raise, a za planter as well. So follow what I'm doing. Let's give it of all of this. We're gonna go char buff for buffa 5 12 or whatever. It could be 20. Whatever. How? Maney bite. She wants 20. And then what we're gonna do is we're going to say, um, shower, um, ask risk for pointed equals stuff. Remember, you wouldn't don't use the m percent here either, because it's ah, Ray. Right. So just by going buff, it will give us the address. Um, so now you should be able to do things like this. 0.0 equals a point of one. He could be pointed to equal C. And if you do print af percent c foot shark on, then you go buff one. We should see a B. Let's give that a go May and we see B. So that's how you create pointers to a raise. So, essentially, you just do that, Andi, you can access them like this. That's the thing about the array index in C. You can access them through pointers such as 012 on the pointer on Gittel. Pick the correct element. But remember, there's no bands. Check in and see as discussed before, So you do need to be very careful with that. Okay, Let's now try a pointer of pointer. Okay, so what we do to do that is I want you to do firstly create in Georgia called a and then we're gonna go inside your ask risk. P equals AMP Sunday, and then we're going to go into your ass, Chris. Asterisk p two equals np. So I hope that explains the multiple asked risks now. So when you have to ask risks, it means that it expects you to point Teoh to a single pointer. There will, That's what it means. And if you had three, if you had three of them, then he would expect you to point to a, uh, two asterisks point of arable. So that's how that works, right? You see what I mean? And then what you can do is you can do things like this. So, for example, let's say I want to change the value of a frumpy too. I would go asterisk asterisk p two equals 50. And then if I go there, compile that. Oh, forgot to print it out, guys. Print f percent I and then we're gonna go a and also we're gonna change it from 50 because the value started 50. So just 25. We do this till May. This is 25. So can you see how that works? So when we do one ask risk on P two, it takes us to this. Okay, It takes us toe variable p here. And when we do to to ask risks takes the value that p is pointing to takes us to back. Which points to eight. I knew if it was three ask Chris, it would be the same. It would take us to the 2nd 1 and then 1/3 ask risk would take us to the final one. I just do that quickly just to show you and hopefully three will make it very clear. If not, send me a message. I'll explain further so we can go like that. We compile that again and you can see that works. So we go ask a risk asterisk asterisk which finally takes to eight. So you're probably thinking, Well, what's the point of having multiple of these? While there's a good point for it, sometimes you might want to change the value that a point is pointing to. For example, And just to show you how that can work I'm gonna create another variable and stripy and say Say we want to change where p two is pointing to what we just do P two equals m some be I really is that simple, right? And then if you want to act if you want to change variable b, you do ask Chris asterisk p two equals 30 and then be will become 30 right? Ming City. So the great thing here, then, is that we can actually change p. So by doing by doing ask Chris P two equals m some be inside your pea here The pointer will no longer point to a It'll point to be so literally we can also do. We can also do this just so I can show you quickly. Weaken, Do ask a risk. Pee in here on You should see. But wait a minute. Did it? Did it? Did it? Oh, yeah, my mistake. We also change it here, guys. So we go ask a risk p two equals m percent b And then if if we can pull out, then we see 20 because p now points to be let me just go through this with you because it does get a bit of a bit confusing, doesn't it? So you go equals 50 b equals 20. So we create to two separate variables and then we carry a point of bearable Hopi, the Points Toe A's memory address. Okay, then we carried a double point of Value Co p two. That points to the point is memory address. And then finally, what we say is, uh, we say get the value of p to go to it because it's a memory address. Go to it and set it to the address of beat. Now, because P two points to the address of P, we set the value of P to the address of B the Islamic sense. So then we change where p is pointing to. So that's the whole point of those double pointers because it allows you to change where other point is appointing to. So it's quite a handy feature, actually, um, in the C programming language. So that is pointers on memory addresses. I hope that clears it all up. It probably is a bit confusing for you. Just go back through the video, watch it again and it will come to you. Takes a while to understand pointers. Thanks so much 11. Function Pointers: Hello, guys. And welcome back. So we're gonna learn about function pointers now. So function point is a like normal pointers. Apart from we point to functions instead of variables. Right? So let's first create a function called my funk. That takes no argument. So put a void in the arguments there. And I wanted to do print F Hello world. Okay. Now, as you know, you can call that like this, Andi, it will work just fine, but we don't want to call it like that. We want to call it through a pointer because the function point is allow you to point to functions and then call that function through the pointer. Pretty handy feature. Right? So to do this, go avoid brackets, asterisk pt off a point, and then do two brackets again, and then we're gonna point that my funk, the address of my fund just explain this a little bit. So we create a pointer to a function and this pointer expects us to point to functions that return type Lloyd so functions that return void. It also expects us to point to functions that take no arguments. In our case, we just provide here for no arguments, right? And this should be pretty self explanatory. Now PTR is the point of name. So that is how you do function pointers. So if we do something like PTR now like that PT on, we do that. We basically call our function through the Pointer. So when we do PT, I says, Okay, what is the PTR function point of pointing to? Oh, it's pointing toe the address of my funk. So then let's run the function at the address of my funk on it. It'll literally run the my funk function because, Anderson, my front gets the address of the function where is in memory and then PTR contains Theodore s the memory address of the function. And when we do PTR and we go to call it like this, it goes and finds the address in the PTR bearable because remember, point of variables are are contain addresses. And then it goes and says, Okay, we have the address. Let's run that on a run at the address that is stored in this PTR variable, which in our case, is my fund. So it's just compiled at a minute on a run that one second and you'll see. Hello World. So that is basically function pointers for you. So just to demonstrate, let's make another function called test funk. It also takes a void. Drink a test function. Okay, nice. So now if we change this here to test fun and then we can probably it again It says undeclared. Why? Because I accidentally did a capital so it can't see is case sensitive guys. So we run that now. Andi predication print f and we run that now and then We do main and it's says test function. So essentially, what's happened is our pointer now points to test function on. And when we call pointer like this, it runs test function so you can see how this is put together. Right? So the function pointer takes a return type. It has a terrible name and it has function arguments. That's how it works. So if we was to create another function, that's called it my son, you know, we did the my son before. Let's do that again. On we go return a plus B on Les Curate. A new pointed for that. So how does it work? Well, you do. Um in Georgia brackets ask us PTR PTR is the function name, by the way and you go in it in it equals on my son. So that's how you make a function pointed to this function. So you should be able to see the resemblance. What's going on here? Right. In this case, our function pointer expects a return type of introgen and it expects to arguments that are both Introgen. So you notice we don't provide variable names here because we don't have to write on now If I do PTR 50 50 50 25 just show you they're different and I go into your result equals PTR 50 25. I can then do print f I results. And if we compel that now you see 75 So can you guys understand how that is working? So once more than just in case we create a function pointer that expects to return type of introgen, it has a very real name of PTR. So this could be anything this could be ABC, right? And then you you have to call it like that right on. Then it takes two arguments inside you and Introgen. So this is basically saying we want our function pointer toe look like this. So any function we point to has to look like this, it has to return, interject, and it has to take two inches. And obviously, the M person here gets the address in memory of the mice, um, function. So this will return some sort of number on this number is the memory address on. And when we call ABC, it will go in and look at our memory dress, and it will start executing at that. I mean, at that memory address, essentially running the mice, um, function. So that is how function point is work. Hope that sums that up. 12. Structures And Structure Pointers: Hello, guys. And welcome in this tutorial, you're gonna learn about structures. So structures allow you to combine variables into a single entity. They're very, very useful. So follow my lead and I'll explain as I go along. So, structures start with Instruct Key would on. We're gonna call this my struck on. Make sure there's a semicolon at the end here, guys. So struck my struck. So this means we're creating a structure called my Struck. Now, this is not a variable name. This is not a structure variable. We actually defining a structure right now. So in here less do inched a, um Charles B. Just a quick example. So what we've done here is we've created a structure the holds an intra job named a on a char character. You know, one bite named b and what we can do then, in arming function, you could do instruct my struck. Yes. So what is this then? We've created a structure variable that is cold s a structure variable called s. That is basically an instance of my struck. So then you can do things like this Estar a equals 50 s Don't be equals C on Look at that. So that's what a structure is. So then you can pass this structure around two functions on stuff like that to make certain things happens. For example, if we do avoid Prince Construct, we can say struck my struck and then we can do a pointer here, guys ask a risk for pointer because this is us. This is that we're making a We're making a structure pointer right now, and then we can do things like this. So what you can do is you can go print f i space C percent I percent c and then we can go s , uh, a S B. So, obviously, where this is going to do is when you pass a structure to this presence trucked function, it is gonna output variable a and variable B. Now, you probably may have noticed that here we're doing a dash and a right Arab While I was here, we're doing adopt. So what's all that about? Well in See you access structure pointers using a using a dash on a right Arab, but you access structure variables that are that are not pointers using a dot. So that's that's That's the difference that so we can do this. Then we can go Prince trucks s but you need to do an percent. Let's complaining print and percent because we're getting the address of s. So what happens here is we create a structure that is of my strict and it's called s we set variable A in that structure to 50 we set for it will be to see we call Prince trucked on. We use the ampersand to pass the address of s So again this becomes a number that represents the memory address of the S variable. So what happens then is we go in here way. We say that we want to print a introgen on a char using these percents on. Then we pass in the Eva Eva the a value on then the B value on. We used the dash on the right arrow to access the structure pointer. Whereas if it wasn't a point, if it was just like that, you would use a dot to access that. So let's now compile that on Do May on you can see 50 c so that is structures for you, and that is structure pointers. So that that is it pretty much works similar to the way pointers would work for in judges. Apart from we don't access them using a ask risk and then the variable name. Instead, we access them using the variable name on a on a dash on a right our and that's how we can access the individual elements so structures construct or any variable type on their great for collecting data together. I, for example, let's say you are making a program that handles books. For example, you might stole the book title. The book description when the book was published, said. You could have a struck cold book and you could start all of that in there. So allows you to organize your variables much better, and it leads to a much cleaner code base on more flexibility. So that is structures, guys, I hope that helps 13. Preprocessor: Hello and welcome on in this lecture, we're gonna learn about the pre process er now the pre process is a compile time land which built in to see and it allows us to control the way things were compiled. So for example, what I could do is I could say, if death test and if and then I could say Roy test. Now if you compile this, we won't have a function called test way. Just won't have one because test is not defined, you understand? So the compiler will see this. It will go through the code it'll say is test to find. No, it isn't so. Let's not do us in here. That's what it will say Now. If we do appear to find test, then this code will be compiled are just to demonstrate this. Let's do test here to call that. And if I go up to here Andi, I do that. It compiles find if I do main, it works fine now guaranteed to find test here. Try to compile that again. Look what happens. Oh, inflict declaration of function test. And then it fails to link because the compiler never bothered to compile test because test is not defined so hashtag if death means if the definition is defined on the definition, were checking that was defined his test. So that's pretty straightforward, right? You can also do some pretty cool stuff with this. Like, for example, I can go to find a B C 50. And now, if I went into a equals ABC a becomes 50. So that's a brief overview. The process so far, you can do much more complicated things with this, such as allowing function arguments so I could do something like ABC X today. And then I can do on that. I could call a function here. Maybe so I could do, um, print F I, um, On that I could go I again for to introduce. And then here I could go, um, accident a right. And now, if you did a B C five and 10 on notes hiding place emmick along because I put one here in my definition. But if you get rid of that, then we ship but a second colon, do you get it? So if you compile back now, can you rather that you can see it says 5 10 So what we've done here, we haven't created a function. This isn't a function right now. We've created a kind of macro function. Ah, pre process of function. So this isn't ABC here is not actually compiled into our program? A tall what happens is the compiler comes in. It says, Ah, okay, you want it. So whenever anyone does ABC and passes to values, we should instead replace this with print F on the values that they entered. So what happens is the compiler comes to it, sees a b C 5 10 on. Then it replaces it with this line eight. It literally replaces it with that. That's what it does on. That's why if you put a semi colon here, you don't have to put one here for that exact reason, because it literally takes this, replaces it with this and fills in the values. So that's a brief overview of the process. Er, it's very good for things like, uh, checking, checking that certain values meet certain criterias a compile time, such as, you know, if you're doing kernel development, for example, you might want to check the actual kernel version meets a certain bounds and then you know you can do things like that at compile time. Eso processors. Very powerful tool on that is just a small example of what it can do. 14. Headers And Object Files: in this lecture, we're going to be covering Head of Falls and Object Falls. So we've briefly discussed how including this head of foul here gives you access to print functionality on the ability to read data in from the keyboard. Well, we need to be able to create our own head of fouls so that we can share parts of our program with other parts of our program. Or if we wanted to create a library which will get onto later on, we would need ahead of filed to be given to the people who want to use our library so so that they're so that they're compiling, knows how to talk with our library. These air old great uses for Head of Falls so essentially had a files they store, they store definitions and function prototypes. They can store structures as well, basically construe or anything that we can store in this file. But the main purpose of head of falls is to export functionality to someone who will be calling our functions or accessing our library in some way. So yes, and this lecture we won't be creating a library will be creating object files and head of files. So let's get to it then what I wanted to do, I want you to create a new foul called test off. See? Okay. Called and inside here, we're gonna have a void function called my test. It takes void. No arguments on we're going to include the STD Io header files so we can output to the terminal again. Um STD ioo dot h And I just want you to print Hello. How are you on your lying there? Okay, cool. So the question Now, how do we access my test from maine dot C one? They're in completely different files. Well, that's where you would use ahead of file for. So by making header files, you can share this product type. So what I want to do is I want you to create new follicle test R h h for head, right, And we're gonna go in here. We're going to go if and death again, we're gonna be used in the process. So here, test under school. Hey, h. And if so, what does this mean? It says if not to find, compile waas ever between here. So if test underscore, hate is not defined compel wherever is under here and then we just do to find test hates. So this only happens once. Now, what this does is if for whatever reason, the same head of foul was loaded twice. We we you usually wouldn't want the same co being run twice or three times or being compiled multiple times. It can cause problems in some cases as well, such as life, troop cuts, symbols, stuff like that. So what we do by using this macro here, it'll only define it once. It will only run what is in here once. So say we define a structure in here, Andi, I don't know. It has an interest. Your be on we go struck a ABC, then this. This ABC will only be declared once rather than multiple times without this. If for some reason, the test rth was included more than once in the same compile ation process, which could quite easily happen, then it would likely try to define ABC twice, leading it to being defined twice, which isn't legal. So by doing if not deaf test page, this will run on. Then we defined test H and then we know this code will never compel again. It will only be compelled once, and that's what we want. So you define everything in between here, Ideally, a scary to that them. So we go back to test. Upsy so we want my tests to be accessible throughout the program. Right? So we can't be its prototype. We go back to test a h paste that in. Okay, cool. So now if we want to be able to access this from maine dot C, we just go to Maine. Don't see him. We go include double quotes, test that h. And now we can call my test like that on this works because what happens is we conclude test our hates when we compel mean that. See on that sees that way we have this on. If you remember what this means when you just do this without the without, without the curly brackets here, what we're saying to the compiler is, at some point in time, you're gonna come across this. This is what it looks like, but we're not declaring it here. So any time we access this, allow the code to compel because we're going to resolve it later and I'll tell you where. I'll tell you the code to run for this function later on. That's what we say when we do this. When you do this, we say, Okay, I want to create on my test function. We know what it looks like now run everything in between here. When you say this was saying, I know what this function looks like, we don't know what it is yet. Just storage it, just allow it allow it to be used on will resolve it later. That's what that says. So when we do this, when you compile, test out, see it composed of my test void here right on. Then when you link the test object on being together, that's when it finally resolves it. Later, it resolves my test on. We'll explain more about Lincoln shortly. So in here it's also good practice to includes the head of file. That's you. I tend to put it at the top. What? When you're including something relating to yourself? Um, so it's common practice to include the head of file that's associated with your see file. So in this case, we've created test. I hate to output things to people who want to include the test functionality. Right. But, um, I don't have to include test. I hate because there's no variables in here are all structures I'm gonna be using here. But it's good practice to do this anyway, because, you know, it matches the prototypes with what you declared anyway, but it isn't a requirement. You don't have to do it, but it's good practice. Um, obviously, if you if you had, like, structures in here, whatever that you'll be accessing inside this far than you would have to include it, right? Okay, that was a mouthful, right? So that's how you create the head of foul on. Now, what we're gonna do is we're gonna actually compile our program, and I'm gonna explain the linking process to you. So let's do that now, what we're gonna do though, too. Hello? Well, dad, And what we're gonna do is Weps. What we're gonna do is we are going to do open up command problems, go C d right, click. Good. And now we're going to do things a little differently now. Firstly, we're going to compile it the way we have been doing it. Just so you can see that there's an error on. I want you to see this era so I can explain it to you. So if you go GCC main dot C Dachau main on. There should be a problem with this. Yes. Undefined reference to my test. Okay, now, I'm glad this happened is now I can explain this problem to you. So remember, main includes test on page. I remember I was saying that when we do this without Curly's were basically saying to the compiler, Allow us to use it and we'll tell you what it is later remember, I will resolve it later, I said, Well, guess what? We didn't resolve it later. So this is the Hlinka complaining that we haven't resolved this way. Said we were gonna resolve. We never did. That's the Lincoln complaining. Right? Um so undefined reference to my test is because it can't find the code for my test because we haven't told it where it is. So how do you do that? Well, we first need to compile tests topsy before we compound may not see because right now we compile only mean don't see you see, so use a different flag in the compiler for this. Do GCC on. Then I want you to go Dash c and when you test stop See? And I want to go Dash o test r o press enter. Okay, Now you can see that what's happened here is is compiled tests Nazi on its output It a follicle tester. Oh, which is a compiled for a compiled object file on what Dash C means is it means to create an object fell. It means we don't want to create the full program. Right now. We just want to create a part of it, so create an object foul, and we'll do something with that object file later. That's what this means. So if you click on here now, it's going to say the binding filed. You wanna open it? I'm gonna press. Yes. You see, that's all the compiled data there, right? So it took test out, see it compiled this function and put it into test. Oh, on right now, we don't have a fully complete program because our programs currently composed of an object fault. So now we need a link that with main dot C and once we linked with main dot c Everything will be resolved in nowhere. My my test is and everything. So how do we do that? Well, then we go. GCC main dot c Space test R o space Dachau main. I'm press enter. And now if you run main, you can see Hello, How are you? So let's explain this briefly this final compile line here. What we say is OK, we want to compel main dot c You're gonna need to look in our tester o object foul the compiled object foul. You're gonna have to look in there for any dependencies. The main does seem I have because we probably defined them in here. And then that's what we're saying, right? And then when Dachau main means output file, you know, main don't yet see again. So that's how that works. Because we tell the compiler if you just do this without the test other what? You know, You get that in defying reference again, right? But when you say test r o, it will check test. Are those object file to see if this my test symbol is in there? And if it is, it knows the code to run whenever you referenced my test. Andi, this clever stuff on it also allows you because of the way object files work. It also allows you to write programs in multiple programming languages on Compile Them Altogether. Anyway, it's quite clever stuff, you know. The link is quite good, so you can have other stuff here to let's say we have an object file called ABC Dough. You just do that. Hello, Dato. You just do that on. What would happen is that we're compartment Nazi and it would look for symbols and all of these falls. That's what would happen. And then finally, Dachau Main gives us our object. Filed our final running running object felt, which in our case will be an e x c fell because we're on windows. So you know, that is how that is, how head of files Andi object files work on. At some point in this tutorial of this course will be doing libraries, which basically is even is quite clever, allows you to share functionality with other programs, but we'll get to that eventually 15. If statements: Hello, guys. And welcome back today, we're gonna learn about if statements. So what is an if statement well in See, you can do things such as conditions. So I can say if variable A is equal to five, then do this particular action else if it isn't equalled, if I do something else so I can explain all of that today. So what I want you to do is I wanted to go into a equals 50. So we create a variable of interest you type on. We said its value to 50. Now I need to go. If a equals equals 50 make sure you do equals equals because equals is assignment equals, equals is comparison. So if a is equal to 50 then print F A is equal to 50. Okay, so that is an if statement. So if we now compile Ah, program. Um, by copying the path, going to command prompt, like before CD, right click. Enter on. We do GCC main dot c, Dachau main, and then we run main. You can see a is equal to 50. Now change this value to 49 or 40 or whatever. As long as it's not 50. Right now I know you said I know when you to compile it again. I'm pressed tight main again and you see nothing. I put it because what happens is it goes in here and it says is a equal to 50. No, it isn't equal to 50. Do nothing. That's what happens. But now let's try this else. If a equals 40 equals equals 40 so then if we print f A is equal 2 40 So what will happen here is it'll say is a equal to 50. No, it isn't. Okay, then is a equal to 40. Yes, it is. Run this code. So if we now compare all that we do may you can see a use equal to 40 if you now do else. If a is equal to 30 and you do print F A is equal 2 30 then if a is equal to 30 that'll be run. But if a is equal and none of these and nothing will happen So if we do 35 in here, we compile that nothing happens. But now you can do in else. So what this does If a is equal to 50 output A is equal to 50. If a is equal to 40 output is equal to 40. If a is equal 30 output A is equal to 30. If it's equal to another these then run the code in here, which will be print f none of the above. So now, if you know, compile that on do may none of the above is show. So that is if statements on you can haven't else with only one If just like this. So we can say if a is equal to 50 print that l spent that. So now if we can, Paul, that none of the above his show. But if we set a to 50 and we compile that A is equal to 50. So that is if statements for you in the C programming language very handy and necessary feature. Now I want toe make the distinction between expressions on statements. So what I wanted to do, I wanted to go into Egypt. B equals a equals equals 50. Now what happens here, then? Well, when we said there will be, we say is a equal equal to 50. If it is, this is replaced with one otherwise is replaced with zero on This has done a run time by the way. So we now go print If I supreme an insta and we pass him be we now run that with GCC and we do make you see one Output it now change change 8 to 30 and run that again and you see zero . So I want to make that distinction because this if statements are an if keyword andan expression. So this here that I've highlighted is not is not an if statement it isn't on I want to make that very clear. So what we do here is in should be equals A equals equals 50 He becomes one if a is equal to 50 or become zero if it isn't so. That was important distinction to make Now watch this inch to be equals one. And now if you do if b and we go in here print f B is true. Okay, now if you can Paula, you can see B is true Now If b is equal to zero and you compile that nothing is show So essentially the if statement if the value past here ends up equivalent a ting to true, which is above What about zero? Then B is true if you put 50 here and try that, Paul, that B is true. So if it's non zero B is true, if you put in zero in here, compel, elect nothing show. So the if statement says If this expression equivalents to true, which is anything above zero, then B is true. So I hope that sums up the expressions there. Now there are special things you can do to sort of flip true to false and false the truth. So how does that work then? Well, if you say B equals one on in here, you do explanation Mark be. And I want you to run that you can see nothing's displayed. But if you now change, beat a zero and you compile that run, that B is true. So this operator here flips it from from true defaults or from Foster Troop. That's what that operated. Does Andi again? It can be used here if you set one toe. If you said 801 on, we're gonna print out. Be again one second. Andi, you now go. Explanation. Mark A B equals explanation. Mark a If you can pilot now you can see be a zero. But now, if you set a 20 can L C. B is one. So how does this work? Well, because a zero we use this special operator here which flip zero toe one, which is true. So I hope that explains if statements please do go back through the lecture slowly. And listen again if you didn't quite understand or send me a message about that. 16. Operators: hello and welcome guys. And in this lecture, we're gonna learn about operators. So we've already briefly done a few operators while actually doing this course already, but now we're going to go a bit more in depth. So the first operator I want to show you is this one. So if we go into X equals one above two Now, what this says is one above two. That's what this right arrow is fall on. It returns true. If it is on false, if it isn't so again, you can use this in an if statement as well. Which might be clear if I do that, actually, on what we can do, we'll just do is X above to justice clearer for you. So in this scenario, it says is X above two. If it is run or Severine here Now, let me show you the above equal operator. So is the right our an equal sign. That means if X is equal to two or above to then run the code in here and in here, right? And then the left arrow means is X below to if it is run the code in here and the left arrow equals means is X below equal to if it is, run the code in here. So there's some of the comparison operators and you already know that equals equals. If X is equal to two, run the code in here now, the does no equal is the explanation marking the equals. So if X is not equal to two, run the code in here. So that s it that they are the operators for comparison there on you can also do things like this. So what does this mean? If X does not equal to or X equals three, then run the code in here. That's what that means. This is the all this is that these two lines mean Or now let's try this and share y equals one. So if X is true and why is true, run the code in here. If X equals zero and why there's no equal one. Run the code in here if X equals zero, and why equals one. Run the code in here so you can use to m presents. So basically combine logic and you can use two of these lines. It's a combine logic. So both of those operators allow you to combine logic when doing comparisons. So let's talk about these other operators that I'm sure you're aware of. If you have used to calculated before, uh, why equals X divided by two. So this forward slash means to fight. Why equals X? Ask a risk to that means why equals X multiplied by two. Why equals X Plus three? This means why equals X plus three. So essentially add 32 x Why equals X minus three? So minus three from X, That's why will equal why equals X percent. Three get the remainder. So the percent is for remainder. So so it divides on gives you the remainder. That is what the percent is for. 17. Loops: welcome, guys. And in this lecture, I want to discuss loops. So loop sincere. Just like loops in real life, right? It's kind of like something The loops around the round and round constantly. Well, And see, you also have loops. So there's the full loop, the while loop on the do while loop on. We're gonna discuss them all right now, So let's create a full loop here. Copy what I'm doing, and I'll explain it as we go along. So you represent a for loop with the four key word. Then you have brackets. You have an initialization, which is here. You have a condition which is here, and finally have a loop which is here. So what this means is create a loop that has a account of arable called I the sequel to zero and you can see that's an insurgent. And then it says the condition for this loop is that I must be below 10. And then it says at the next iteration of the loop increment I by one. That's what the plus plus means. So essentially this this this loop will Luke 10 times so we can demonstrate this by doing print off by N for New Line. You know that the that the backslash end for new life and emperor I am here now. If we compile that what may not see guys not see PP mental See And after type main you can see it says 0123456789 So its output of that 10 times Because I start zero here on you know , this could be below equal right And then we would see 0123456789 10. So you know that the condition is basically an expression much like explains And if statements where you can have equals, equals does not equal above and all that sort of stuff So these are basically four loops. So what is basically happening is anything between these brackets here, which is a scope, by the way, you know, scope is anything between these brackets. So anything between these brackets of the four loop is basically being run on a loop. So what happens is we come in here, we create available, called I. We said it zero. We then check if eyes below equal 10 which is So we start running the loop. So we basically print print the I the I variable value. Right. Then we leave the loop, causing I to increment by here. So then I becomes one. So then right now I is one. Yeah, and then we check this again. Is I blow equal 10? Well, I is one, so it is below equal 10. So then we run this again we output the I've out the eyes value and then we leave the loop again we increment I And now I is equal to two on we go on and on and on until this condition is no longer met And then the loop ends So that that is basically follow ups for you So let me show you how you can count backwards. Let's set I to 10 And then we want to change I to say above zero and then changed I plus plus I minus minus and 1/2 We run that Compile it First you can see 10 987 and so on. Now how that works is we set I to 10. We check if I is above zero. Well, I is 10 so it is above zero. So we output at the ice current value and then we deck remit. I buy one. So now I is nine. I is still above zero because I is nine, right? So then outputs this again. So follow ups very powerful. And they used all throughout the C language when you're making projects. Okay, let's now discuss the while loop. So give it to you. Followed on. We're gonna go while one. So what this does is this runs everything in here so long as the condition between these brackets is true. So remember what I said before One is true. So everything in here will be run forever. If you do print f hello world and you can call that and you do main. You can see it says hello. Hello. Hello. Constantly, Really fast. Right. So that is wallops for you. So if we wanted to do something like this um, similar to our fault, we could go into a I equals zero while i below 10 on again. This will be infinite at this point currently because I zero says below 10 right? But now in here you can go I plus plus and now, if you was to compile that, it would work similarly to the follow up. You see 123456789 10 Its output Hello will, 10 times so that last wild lives for you. But you can also in on this applies to all the loops. By the way, you can leave a loop early for whatever reason, and you do this by using the break key would. So, for example, let's say if I is equal to two break And that's another thing, by the way, when using if statements or any statement told, you don't actually have to use the curly braces if your if your code is only one line long . So in our case, we only have one line with the if statement, so we don't actually need thes, and it will run that one line and leave. If you need more than one line, let's say we want it out. Put a message here and break. Then you can't do that. You need to use the curly's, but for one line, you can use it. So essentially, if you're if statement is only gonna have one line inside the body between the brackets between the curly braces. Then you can use just on the line on its own without the's. Curly's literally just like that. And that will work. Fine. So what this is going to do now? We're going to come in here and as soon his eyes equal to two, we're gonna leave this loop. That's what the break keyword does. So let's run that now. Compile it. First you can see it says hello, world. Hello, world. Hello, world. So, as soon as I is equal to two, we break from the loop. So in addition to break, you also have the continue keyword that allows you to skip over an inspiration. So I'll show you how to do that with the for loop. So what's this Then? We're gonna print out the index as before, and I'm just gonna compile that to show you that that works Fine. You can see that. 0123456789 Let's skip over three. Yeah, So if I equals three, continue. And now if we can polit now, we can see it skipped over three. We have 0124567893 Isn't output it now? Why is that? Because we go in here, we say, If I is three, then continue to the next iteration of the loop. I want to leave this loop for this situation and pretend it never happened. So then it immediately skip straight to I plus plus and stops executing here. And then obviously I then becomes four. And the loop continues is I call the three? No, it's for So continue is never called again and we print as usual. So the final loop I want to show you is the do wall loop. So let's do do owe on it filled it him for us. Brilliant. So essentially it's similar to the while loop, apart from the condition, happens last with a traditional while loop. What happens is we say while this expression is true, run this code whereas in a do, although we say run this code on if the expression here is true, run it again. So that's the difference here on just to demonstrate this If I do print f first loop and then I do print f second loop And now if I go to here and I compile again. I run that you can see Second loop is output ID. Let me just do a break here as well so we can leave, cause that's currently an infinite loop. Right? So you can see the only second loop is out. Put it on. Why is that? Because here it is false. So this never gets run, but with a do while the codes run first and then the expressions checked. So if this was zero and we try that again, we can see second loops still runs even though it is not even though it is not true. And just to get rid of the break is well, to show you that isn't what's leaving. You can see second loops still run. So essentially the expression here zero. But because the codes run first, it doesn't reach this expression until the end. So it knows not to loop back around. But it will at least 21 loop, because it's a do well, whereas the while expects the expression first on because it zero it never gets run. The do while runs the code first and then expects the expression, which is why we get second loop. Even 10 is here. If you have true here, it will be an infinite loop. So that's do while on the difference between while and do well. So I hope that makes sense. Please send me a message. Do you have any trouble understanding that? 18. Legacy C: good afternoon and welcome. I wanted to show you some legacy C. Now some C compilers used the old standards, which means there's more rules that you have to follow on. They were removed and replaced better standards. Um, so, for example, in certain versions of of C language, you will have an error or a warning. If you define variables underneath function calls or even if statements now in old style, see, variables have to be declared at the top. They have to. So that's an important thing to note right there. How you get around this without with an old compiler is you can do things like this. So by putting those two, um, races, anything you define here will count is a new scope. So it will work. The same applies for if statements. So this would be legal. Uh, but this would not. So the new scope basically resets the rules on allows you. Teoh defined variables at the start in scope, but it has to be at the top of the scope. So that's basically an important rule in old style. See, is that variables have to be declared at the top of a scope So it makes you remember that there's ways to get around these rules, which I'll show you laid up in a moment. The next thing I want to show you is I showed you four lips recently, right? Uh, on certain versions of C, you can't do it like this. You have to instead do it like this. I know it's quite silly, right? That's why it was replaced with a better standard in the newer versions of See You Can. You Can Do It like that and there's no problem. So if you wanted to be able to access new of functionality and your compilers complaining, you could always try and change your standard on the compiler. It is a modern compiler. It might be using older versions by default, so I can show you how to do that. Now, when you go to compel your program, you essentially go to compile it like normal, and then you do STD for standard See, standard basically equals C 11 on that should push you back up to the newest standards. However, if you're compilers legacy, it might not know about standard C 11 in which case look for the highest standard for you, compiler. You can, or or or replace your compiler with a complete new one. Um, so, yeah, that I hope that covers legacy. Seaga's I was quite important to get across. 19. Nesting Statements: Hello, guys. And welcome on in this lecture, we're gonna learn how to nest statements. So, essentially, you know, we've bean talking about if statements and stuff like that, Well, you can actually ness them. So how that works is, uh it could be like this and then you can say print f hello, world. So then what will happen is if this is true, which it is, this one, it will come in here. Then it will say, If this is true and it isn't so, we'll never get run. But if both of these conditions are true, then it would run this on. This is called nesting Where you where you can nest statements down and down and down. But you should be careful when doing this because too many statements can make the code look very ugly. Like, for example, if I keep doing if statements constantly going down Look how ugly it starts to look, right? Yeah. So what I tend to do to get around there is let's say there's a function that is taking some arguments and you want to check that the data is legal or valid first. What I do is I check his legal or on valid. And if it isn't, then I just return. I just I just returned from the function, you know, usually it would be a void or something, and I would just return. Oh, I would pass back estate. So that way, then you can just do your if statements is normal because you know that you finished the execution program so much like if statements, four loops can also be nested, all statements can. So, you know, I could do something like this. So if if this statement is true, which it is, run this followed and then print whatever is in here. So I just wanted to demonstrate that you can nest statements, so it's quite an important thing to get across. 20. Global Variables And Positioning: Hello, guys. And welcome back in this lecture, we're going to discuss global variables. So currently, we've discussed local variables which are simply variables declared in a scope. Now, a global variable is a variable declared outside of the scope, such as here, for example, on what we've now done is we've created ABC variable that could be accessed through multiple functions so ABC can be accessed here, or it could be access here. Now. What if we create a variable named ABC here? What happens? Well, it works. Instead, This ABC will be set online. 12. When we say ABC equals 30 it will change this one. Not this one. Now, in C parables can share the same name so long as they're not in the same scope. So, for example, this is not allowed. However, this is allowed. And if we was to do ABC equals five here on, then ABC equals 10 here. What would happen is when we enter, what would happen is here we create a variable named ABC. We said it to 20. We now create another vary variable called ABC that is unrelated to the one online 11. Here. We set this 1 to 20. We then set this one again to five. Online online 15 here. We now believe we now leave this scope so this variable gets removed. Deleted is no longer accessible. And if you want to try and access it through its men readdress, it would be undefined behaviour. As explained in previous videos. When it comes to scopes, when you leave a scope, the variables can no longer be access safely. Now online 18 you can see we set ABC to 10. Now, this changes this one online 11 not this one, because this one has disappeared forever. So not the one online fording it changes this one. Now, if this wasn't here and we did, ABC equals 10 it would change the one in the global scope right here. So I hope that explains global variables on how variables can share the same name on separate scopes. So it always picks the one that's the closest to the top of itself. So insure ABC was 20. It would pick this one because this is the closest of the top of itself. This wasn't here than the one here in the global scope is the closest of the top of itself . So that is how it works. 21. External Variables: So let's explain external variables. Copy what I'm doing. So what we've done here, we've created a global variable called ABC, but we've marked it is external, Which means that which, which tells the compiler we're not creating a variable by here. We're just letting you know that there's a variable somewhere in our program called ABC that exists. So if I was to do ABC equals 50 here on, we were to compile that, um, what would happen is you would see undefined reference to ABC because we've said that this is somewhere else on when it comes to compiling. We don't We haven't told it where ABC is. So the compilers thinking Well, you said you were going to tell me, and you didn't. So it basically fails to link and correct your excludable binary, the XY file. So let's define ABC, then. I wanted to create a follicle tests Tazi, and we're just gonna go introgen. ABC equals 50. That's all I want you to do. And now what we're gonna do is we're going to compile a file. So do do GCC tests. Topsy Dachau test r o on do death. See? So that's curated An object foul called Testa. Oh, on. Now, if we now do gcc main dot c test Uh oh. Dachau Main and press enter. You can see it now compiles Absolutely fine, because by including the test our object, we are telling the compiler where ABC is because we've we've defined ABC here, right? We've said insta ABC equals 50. So then in maine dot c when we say X turn Introgen, ABC Where Town The compiler were aware of ABC, but it isn't defined here. Go and look for it when the time comes. That's basically what we're saying. And then obviously when we put in our test out see file here and we compiled it by here into a tester object. ABC is then stored in that object Foul, Right. So then one week go to compile a program completely on. Then we pass test are oh, it links the two together resolve in the external ABC into the ABC that we know that we defined in test artsy. So that's how external variables work. It allows you to mark variables as outside of this source file, and then we can resolve them later. 22. Null Terminators And Ascii Table: Let's discuss no Terminators. Copy what I'm doing. So we create a char pointer with a variable named ABC on we said it toe Hello world now in C Whenever you provide a string like this annul Terminator is automatically appended to the end. Now what annul Terminator is It's simply a decimal zero. That is all it is on. I'm not talking about this a number zero. I'm talking about an actual decimal zero. It's binary equivalent is eight zeros on? Basically, all that does is it represents the end of a strength and C A C applies thes by default. When using strings like this that is very important to note. So computers have character sets and this is a nice little chart to explain them. So you can see over here Capital A is decimal 65 and it actually works like that. If you create a sharp bearable and you assign it to 65 then you print it out with the sea with the percent C for chart, you will see a That is how it works. But the but the decimal equivalent is 65 Now, over here on No, his decimal zero do you understand? Whereas the number zero is decimal 48 so that explains it on. Basically, this character chart is very important because it allows it allows it. So when you type hello on the keyboard, the binary is converted into characters. When it's displayed to you on the screen is converted to pixels the represent characters based off this chart. So that is why decimal zero is different from number zero. So decimal zero, which is Arnold Terminator is decimal zero and number zero, which is not Arnold. Terminator is decimal 48. No terminators actually invisible. Um, on most text editors, they are usually rendered as a white space. Almost there look like a space, almost as if you press the space bar. 23. Character Arrays Vs Character Pointers: Hello, guys. So we're now going to discuss the difference between character pointers and character arrays. So follow my lead. This is a character pointer, Andi. Essentially this data, it's stored in the data section of the excludable. When it compiles, there's a few sections. There's a tech section where the code is stored. There's a data section where data restored on their some other sections as well, which directly relevant for this lecture. So when I do these quotes and do Hello world, this is stored elsewhere and this is replaced at compile time with an address. So we basically point to the address off whatever hello world is when it's compiled. Now the char rays are a little different If we do shar ABC to equals Hello, world. Now this here is stored on the stack or in the CPI registers. When what? When we actually run this code. So the difference here is this isn't this isn't returning a pointer of any kind. This is instead treated as an array on its stored on the stack or in the individual registers of the CPU prose of the CPU. So that is the difference. I hope that makes sense. So essentially, ABC is a pointer. But ABC to is not. If you tried to assign ABC to to ABC so that it points to this. It would not work because ABC to is an array, whereas ABC is a pointer. 24. Typedefs: So we're now going to discuss type deaths on type deaths allow you to create alias names for existing types. So, for example, up here, if you did type death inches job my i n t and you did that you could now do my my aunty ABC on ABC is an interview because what we've said is we've said create a type definition the tigers in i nt for in Georgia the name is my in it. So my in it is now an alias of Introgen so we can actually do ABC equals 50 here Print F percent i ABC And if you go to the compiling compile that and you run that you can see 50 output it So essentially we've just created alias of I NT This could be along as well. And now my in my aunty is now long It's an alias of long so that is type deaths for primitive types. So now let me show you structure type deaths. If we create a new structure up Here we go Strict, I know Record uh on we do this This is our record structure or whatever And it could contain introgen if we want to type death that we just put type death at the beginning. And then we just put our name by here. So now what we can do is weaken go Alias ABC on notice. How we don't need to do the struck keyword is because we typed left it here. So now we can go A B C D a. Was 50. The mash of work just fine. If we compile out now, you can see that compiles Fine. So essentially by type deaf instruct way, we no longer have to provide struck keyword, which is a very useful feature. So if you remember before I taught you about function pointers where you can also type deaf them so they're a little easier to understand. So if we do type death, avoid Bhaskar risk pointer and we do this, then what we can do now we can go PCR p and then up here we can go avoid ABC, avoid and let's provide there as well. And we can now just do p equals ABC. And now if we can pile up, that could palace Fine. So essentially, what we've done here we've made a function pointer type that is for pointing to avoid functions, functions the return no type and take no arguments on. We've named that alias type PTR, so this could be anything such as avoid PTR Void, void F N C PTR, Savoy function pointer. And we could put that in there like that. And now if we call p like this and we print F here hello world and we can pile up, you can see Hello Walls output it. So obviously, defining your pointers like this is pretty difficult, Teoh to understand. So by type definite, it is much more cleaner to create function pointers because now this is very clear. We've created a function pointer that points devoid functions that take no arguments. And we've named the type void funk PTR. So whenever you wanna point to a function that takes no arguments and returns void, you could now just use void funk. PTR. So is much more cleaner than riding this out every single time, then writing what I've selected out every single time. So that's how you can type death, pointers, function, pointers. So there's other forms of type deaths we can do as well. For example, you can do type death in Georgia. Ask a risk. I I ntpc are, for instance, your pointer. And now if I wanted to do in its A equals 50 and I want to create Instru Pointer I could just do I could just do something like that. I m t p t r And then there's are variable name equals AM Sunday and now I can just do a ask risk A equals 50. As usual, ask rece PT r equals 50 as usual. My mistake. We can pilot. Now you can see that works fine. So here we've typed deaf and inched your point of so you can see that it's a little more understandable now than I and she I nt ask Chris PTR So there's all sorts of clever things you can do with the pre process er, because type definitions are are resolved a compile time, not run time 25. Booleans Explained: So we're not gonna discuss Pauline's, and you're probably wondering why I haven't discussed them yet. While the reason is is because see doesn't come with a leans built in. In other words, it's not a primitive type, essentially to access billions and see you need to include ahead of file. So include STD bull dot page. This will now allow you to do things like this. So what this does this creates an ABC variable, and the ABC variable is equal to true. So what we can now do is we can access false and true in C so I can do things like if ABC Prince F A B C is true. If I now compile that ABC is true, I can see that if I said this to false, I can pull out now I can see nothing so you can clearly see that by include including STD Bulldog Page. It defines a macro, a definition called false, this equal to zero. So much like when I showed you how to define things in the pre process. Of course, in the pre process a lecture, you can see that false is equal to zero, and true has a definition that is equal to one. So you use BA leans in situations where there's only two values. 01 true or false yes or no? 26. Unions: so unions are a fantastic feature built in to see on what they allow you to do is they allow to share memory regions with multiple variables, essentially, by changing either one of these variables will affect them all because they all share the same memory region. There are many reasons why you would use unions, particularly in low level code. So let's now create a union. I'll explain as we go along Union, my union, but a semi colon at the end instead a Sharpie. So now in here do union my union, ABC an hour ago abc dot a equals 50 and then do a b c dot b equals 20 and I want us to output A and B So we're going to go and do that now. And what you're now going to see is, if we can Paula and run that you're gonna see 2020 now, why is that? Because both variables in here share the same memory region. So when we set insta a to 50 on, then set Sharpie to 20 we overwrite the memory invariable A because they are sharing the same memory. So that is fantastic feature. If I was to do something like zero x f f f f f f f path on This is Hexi Decimal, By the way, this is how you do hex, decimal and see. And then in here we we keep that is 20. If you now change thes toe X on X this will print now Hex Hexi decimal values for us If we now compile it again, can we run that you don't see f f f f f f f u C f f f f f f F 14 and then the hex equivalent of char B is 14. So by getting rid of this that by getting rid of this, completely removing it Onda we compile that again. You know, see that both a and B equal to f f f f f f f because they share the same memory region. So you can also define unions in structures as I've done here and you'll notice that we can now do Esther A equals 50 s stop b equals 20 on that will perform exactly the same way as I just showed you and obviously above the union here you can have other variables such a Z, whose memory location is not shed 27. Hex And Binary: Hello and welcome. So we're now going to discuss how to use Hexi decimal and binary in the C programming language. So, firstly, if we go back to the asking table, you can see decimal value on a hexi decimal value next to it decimal value. Hexi decimal value. All that this is is the way the computer displays it to you. Everything in a computer is binary. The decimal numbers you see here are just the way it displays that to you. That's all that it is now. That is an important thing to note anything you see, if its capital a a capital B, it is all just ones and zeros on the fact you see A is because this table, the asking table associates those binary bits with our pixel bits. So it knows which character to display on the screen to you. Now, Hexi Decimal is no different. It's just a way of showing a decimal in a different in a different format. So you used decimal and hexi decimal to express binary values. It's all the same things. Okay, so go back to visual code on. I want us to create a variable on set it to a Hoechst s more value. So go in such a equals zero x zero x means the we're gonna We're about to express a hexi decimal value. So the compiler one, when it's compiling your code, should read that value as Hexi Decimal that that's what it's saying. So if we do do X 20 in here, you've Now you've now set a 20 x 20 on. If you do print, if we're gonna output this so I can show you the difference A. Now this will be output. It is decimal, right? So let's now open that up on compile it. So back to cmd cd paste that in GCC main dot c Dachau dot ford sash main and then Dumaine you can see 32. So what this means is Hexi decimal zero x 20 is decimal 32. Now watch this. You can do percent X here to display hex decimal values. So now if we provide a again so a will be output is intra first and then is Hexi decimal Next. If we now compile that again and run that you can see 32 20 So twenties are Hexi decimal value 32 is the decimal equivalent. But let's go back to what I was saying earlier. The thing is, Hexi decimal on decimal and binary. They all equal the same thing. That's how it works. Zero x 20 is no different from our 32 decimal. This this is just the way the computer displays it to you. It is all just binary of the end of the day. It is not decimal. It is no accident. Zimmel. Everything is expressed. His binary on the computer can render it to us in decimal or hacks a decimal, and that is so important to know. So hacks a decimal 20 is exactly the same as decimal 32. It's just being displayed to us differently. The equivalent at the binary level. And that is what you need to know. Let's now discuss how to write binary values and see. So if you do zero p 12341234 And then get rid of this final zero input one. We're gonna change this to a child and put a semicolon there. So as you know, there are eight bits and bytes, so we should have a pet CIA 123 full 5678 Yes, we do. So make sure the final zeros of one. Now we need to compel that I'm running that again so we can see the binary one is Hexi decimal one on decimal one. So to do binary, you stop with zero B decimal zero b. Everything after is by knowing binary values. So if you now get rid of this and put a zero, this should be too, which it is. Put a one here, so it's 11 at the end, and it should be three, which it is. So that is how you can assign binary in the C programming language. You simply start with a zero B and then the rest of the numbers i o binary value. The 1st 0 here means nothing. The following zeros and ones are the value. So the following after the big So I hope that explains hex decimal and binary in C. I know I haven't discussed how the hex numbers on binary numbers how they can be, how you can understand them, But that's because that I assume you already know this. This is a C programming course I'm t I teach you how to use them in the programming language so you can look that up simply. Binary is based to, and Hoechst Estimate is based 16. 28. Comments: So in this lecture, we're going to discuss commenting up until this point, I haven't discussed commenting because I've been wanting to get most of the hardest stuff out of the way. So commenting allows you to basically write comments for yourself to make code a little easier to understand. So, for example, this is a comment. So by using to forward slashes, you say to the compiler, this entire line is not code. It's a comment for myself to understand. My co better on the compiler won't compel this if you did slash slash into a equals 50 it doesn't get compiled is a common. So that's one type of comment you can. You can use new lines at two. You can use forward, forward slash to forward slashes and then a description of what's going on. That's one way to do it. But what if you want to write multiple lines, maybe a paragraph? Well, to do that, you could do this. Everything here is a comment on here, so forward slash Ask Chris to start the multi line comment. These are called multi line comments. Now. Everything else is your comment, and then you end the comment with a NASCAR's forward slash. So to stop comment, forward slash ask risk to end the comment, ask risk forward slash. And then that's how you can write comments for yourself. And it is great for things like commenting functions you can like. You can put something here and you can say, uh, this is the Entry point Teoh application Something like that, and it's much more easy to understand on you. You can actually put in things like this and what this does. Is it still just a comment? But if you put this through some sort of documentation genuine generator, uh, it will actually take these, and it will put it into the documentation and automatically create a documentation for you so you can look into projects called oxygen on Doc. Surgeon basically does this. It will create a website for you based on your programming project. So what you'll do, you will basically tell the oxygen that here are my see files on. Then it will go through. It will grab all the functions that you have. It will put them into the website and then it look for these comments here, but it's important to note Many of these generators expect to ask asterisks to start the comment and not one now in C. You only want to started, but the actual Pazar of the documentation generator looks for two of these in most cases, So then it will come through. It will see this and it will say, Okay, this is a description of function Main on these are the arguments, descriptions of function main. And then it will build you all of this hate html website so that people who are using your project can go through and see everything nicely explained. So that's something to look into that oxygen. So they are the two comments in C. So once more forward, forward slashes for new is for one line comments. Forward slash star star forward Slash is for multi lying comments. Multi line. Okay, so I hope that explains commenting. Commenting is great because it can help explain your code to other developers who are working on the project, and it's a good reminder for yourself. While good coach should usually be self explanatory, insert in many scenarios, you will need to comment, especially for complicated code. Thank you 29. Automated Building With Makefiles: Hello. Welcome back. We're now going to discuss make files. Now, what make files allow you to do They allow toe automate the building of your project. And no, it's not gonna code for you when I say automated building. Think back to when we compile our application with GCC main dot c dash Oh, main. Now this is fine. For one, your program is only one file. Imagine having 30 files and happen to manually do that for every single foul and then linked them all together. That's unacceptable and disastrous. So make fouls allowed to specify a set of rules, and then you can then run it through a program called Make, which will then follow those rules to compile your entire project. So let's begin. So let's start by creating a new file and you're gonna call it Make foul has to be a capital M and no extension. Just capital m a k e f i l e make file. And now what I want to do, I want you to go. Oh, Colon. And then I want you to do in here. New Line Tab has to be a tab. If you use spaces, you'll make foul in our work. Make fell. You can't have spaces for the rules. You need to use taps for the rules. Okay, so we go GCC main dot c Dachau main as before. And now all of you. I wanted to save that. I want you. Then toe open your turn, Immel. And I want you to go. Minguzzi 32 dash, make just press enter and I'll ask Compiled your project. And if we go back to our project, that is compelled it now. So when you run this one command mean you think to make it'll build your whole project. Now, obviously, we only have 111 command here being executed. We want to make it so we can automate the bill for the whole project. So how do we do that? Well, just to demonstrate this, that's great. Another file. Call it test up, See? And in here, we're gonna have a function called my son. It takes two arguments and just call that and should be this fine on all it's going to do is return a plus B, and I want you to copy this because rather than create ahead of file here we're just gonna find Mark this definition in maine dot c So we don't have to create new head of file. So copy the prototype here, Just paste it here because remember, when you include head of files, that's all this is doing is basically pasting this in The father included it, right? So we do that and now main dot c will be able to know that my son is somewhere else in our program. Let's just use it will resolve where it is later, Remember remember, that's what it says when we do this. And I want you to good to go into a equals my son. 50 20. So add those two together print f sent I four slash and a Okay. Now, if we compile that now with Mingo make, you'll see that it has a linker error because we haven't been politesse. Start. See, right, Because we've said my son is in another file or or somewhere else in our project and we haven't on. We've told the compiler Just remember that this is somewhere else uses as if we have it and we'll resolve it later. That's what was saying, but then we're not resolving it, which is why we get this error. Now. Let's now change our make fouls so that it compiles tests topsy as well. So I need you to create and make file variable, which is pretty easy to do. Just go up the top here and do object files equals dot forward slash test up. Oh, that's all I wanted to do. And I went here I wanted to do after this colon I wanted to do percent and in these curly's object files. So what this says is when we build our project, we depend on all the object files in this variable on you. Define more where more object files by doing things like this, right? Onda literally this when we do dollar and in these curly's it literally gets replaced with this. That's what happens. Okay, so here now we've now said to the make foul Okay, we depend on these object falls, so we need to define those further down, which we'll get to. But firstly, I wanted to do in here after May not see Dollar Curly's object falls so again what this does this gets replaced with the value of object files which is test. So if you remember this command, this compiles main dot c on links it against test auto Resolving that those symbols. Now let's go further down here and we're going to create a new label called Test and we're gonna use that colon and then we're going to say test artsy. That's all I wanted to do. Press space. I'm impressed. Enter and then do tab on do GCC test Nazi Dachau test. Uh oh dass sie And what this does Dash C means we're compiling this source file into an object foul and not excusable because remember, the object files get resolved later when we build when we build the final project and we provide all the object fells as we've just done here and it compiles them all together. So if we now go back to command, prompt and we run Mingo 30 to make you can see it compiles test out. See first because we've told it in in the old label that we need tests are go to continue. So it compiles that first. So So it comes down here and it compels this and then the all label is now satisfied. So it runs our final command to compile main dot C and link against Tester O, which was created in the first command here that was executed. So now if we do main it, I'll put 70 which is my son. 50 20 Which runs are my some function, which returns a plus b. So does make fouls on. Basically, when you run make on its own. What happens is it runs the first label it sees, which in our case, is all now You can also define other labels to do other things. For example, here I could find a clean label which should delete those that those object files. So if we now do del 0.4, if we now do Del Test, although and then we do one second editor and then we do a another another. And when we do another new line, we do a tap here. Darryl Main Dxy Press safe. We now run make again menu menu 30 to make. You can now see that composite cause I forgot to provide the clean, So if you do space after that and you do clean, you can see it deletes our program and object falls so you can. Basically, if you provide a label after Mingyu make, then it will run that label instead. So if we did meet you all, it's the equivalent to just doing Mingyu 30 to make Do you understand? So that is make fouls. It's very important that you always have tabs here. If you do a space here, it won't work. Has to be tab. Even if you do for four spaces to make up a tab, it won't work. Has to be a tab. Guys, if you don't do a tab, this is what happens, right? I've done spaces. Now, if we can pilot again if we run that again Missing separator Some of you probably seen that era to fix that. Ensure that all your spaces are removed and replaced with tabs. You do that and then it should work absolutely fine. All right, so that is make files. And that's how you can automate the building of your project. When you have, like, 20 C files. You don't want to be entering this command for every single one of them. So make files allowed automate the whole thing they used in high scale projects all around the world, especially in the open source community. Make is a fantastic tool 30. Casting: so I want to discuss with you. Casting on more casting allows you to do allows you to convert one type into another so less to for example, float ABC equals zero dot now equals 1.5. For example, if we now did interest, you're a equals. ABC um, weaken convert this into back into an insecure by doing this. So bracket i nt racket. And now, if we know output, um, the instructor values for a and you compile that using GCC main dot c. Dachau May you'll now see if we run main one. You don't see one dog. Five. We have basically casted the float from a float into an insurgent. So that's how you can cast with primitive variables. And you can cast to any of these types so you could do char um, anything. So you go Charlie equals char ABC. That should work as well, which it does eso. Now let's discuss how you can cast point a types. So I've written some code here to explain pointer casting. Now you can see we created Introgen called a We said it a Hexi decimal value for 14 to 4344 Now these numbers is so important because if I show you the asking table, we look a hex decimal value for one that's a hex decimal value for two. That's be for three C for four D. Now, as you know, introduced in store for bites by using hex decimal values. This is the equivalent to us saying a is equal to a B C D. Because remember what I said, that it's all binary at the end of the day so you can do this now. Here we create a char pointer, the points to the address of a but we cast it to a char pointer. So then what we can do is we can actually output the's values as if they were check characters because it's old. Just memory at the end of the day, right? If I did point his 0.0.20 here and I compile that you see D if I did point a one you see C 0.22 you see, be 0.23 you see a so we're actually out putting a, B, C and D Just from this interview here on that is quite impressive, because in see you can cast a pointer toe anywhere in memory that you have access to. So by casting a pointer to our insta a as we casted to char to a char pointer, we can access it as if it waas Some think like this. We can literally cast it as if it was that because this will work as well, you see? So what I'm trying to say here is whether use intra Gia or Char, It's all stored the same in memory. See your ex for one for two for 344 is stored Justus. If we made a chart array of four bites and we assigned it to zero x 414 to 4344 now during compile process, you know the optimizer might do some clever things, store things in registers and so on. But from a C perspective, you can access things just like this on. It's completely legal. On it is a common practice. You can cast structures two areas in memory too, for example, fights fine structure here. We'll call it, um, test. Well, Ted, test structure. And here I have shot a choppy HRC Ciardi. I can then do something like this esta a equals zero x for three s Stop B equals zero x four for s dot C equals zero x 45 s top d equals zero x for six. I can now make a child Pointer and Aiken pointed to the address of our structure. Cast it here to a char pointer and now I should be able to just do PTR zero. And now if I know run that we see See PTR one We see d PTR too. We see And that is really how it works. You can cast her any type literally with the pointers you could even cast a char pointer to a function if you really wanted to. It is very powerful feature and is used throughout the entire C language. So back to our original pointer example, you may have noticed these bites were out. Put it in a in the wrong order. Now there's a reason for that. Processes have what is known as Indian iss and essentially you have big Indian on little Indian now big Indian store it as we ride it for 1 44 344 in accident symbol. You know the buying Rick Evidence. However, um, little Indian is a bit different because the bites get swapped. Eso this is stored a little differently. Now. Most processes are little Indian, so you should definitely read about little Indian and Big Indian to understand that more further. But essentially, the bites could get swapped, uh, for little Indian machines, whereas big Indian machines, it is how you write it. And this is also pretty important to note because if you're ever developing network applications, then you ideally will need to convert the value here to a big Indian value so that when you send it down the network, the guy on the other end could read. This is big Indian, because if you have two machines one on little Indian and one on Big Indian and they're communicating over the network, they won't works expected unless they both follow the same Indian nous. So, essentially, if a little Indian machine receives a big Indian number, it will convert it. Teoh Ah, little Indian, when it receives it on big ending machines will do nothing because they know that this is big Indian. The network standard is to send as Big Indian to send inches as big Indian. Now this sort of flipping stuff will only ever happen with primitive types. And when you assign them like this. So when it comes to things like, um, chart chars light, like in the structure we had, where I had a a structure with about 44 charge, you'll notice that was an order. That's because charter only one bite if you short or higher, then you need to take into consideration that little ending machines will tend to flip the bites but definitely read about Little Indian and big Indian. Aziz, they're not part of this C course. 31. Creating Libraries: So we're now gonna explain what a library is. So you've probably played some games in the past, and if you're ever curious and looked into the actual game folder, you would have saw a bunch of DLL fouls. Thes are dynamic link libraries. Now, in the case of a game, these libraries might be responsible for playing music, drawing pixels to the screen, the game, the game develop. It can use thes DLL fouls the library's toe actually make their game, drop Texas to the screenplay, game music and so on. So, simply put, when you create a library, you can allow your work to be used by other developers without actually showing the source code to them without sharing it with them in any way. So we're now going to create our very own library that allow you to some two numbers together. So a developer could use our library to basically call a function called my Son, which will return to numbers. The programmer provided some together. So a nice, simple library, but I really get it really gives you the jest of things. So let's get on with it. Okay, let's now create a library so I want you to do is I wanted to create a new file. We're gonna call it my lip dot c on the name of this. See file Doesn't really matter too much. However, we're gonna call it my lip topsy. So do Incheon. My some It's j in chippy return A plus B. So obviously this is just gonna add a a and b together and return the value. Not here. Do include my lib dot ph. We're going to create a new file called My Lived a Page, and we're gonna go, if not death. My Lebanon School hates to find my lepage. And if and then he had just two inch in my son, in short A and should be. So obviously, by putting this in the head of foul, we can allow other other see files to be aware that this function exists somewhere. But we don't know where yet, and we'll know when we link the program together. Okay, great. So now what I need you to do is I need you to compel my live dot c into a library fall. So how we do that is we get up our hello world up again. We see d into it in command, prompt. And now we're going to compile it. But we're gonna We're gonna compile it a little differently this time. I want to do GCC my lib dot c Dachau, my lib dot dll for dynamic link library. And I wanted to dash ed press enter. And we've now created our very own shared library, and that's all compiled nicely. So now what we need to do is we want main dot c to be able to use that function in my lib. Dll So what we can do? We can go inside here. We can go include my live dot ph and then we can go into a equals. My son five and five Princess, I Hey, and how we compile that? We'll see a problem undefined reference to my son the last because we need toe link it with my lived on dll so you can do that by doing? Um, main dot c My lived up Diello. And now that's compelled. If you now remain, you see 10. Now let me open the project directory again to show you how this works. In this scenario, we have not combined my son into this into the main dot Txt far we haven't done that in this scenario. What we've done is my lived up. The allow is separate from Maine Dxy But mainly I xy relies on my lip Dll So if we just delete my laptop dll now and we try to run that again What's this? The code execution cannot proceed because my lib dot dll was not found. So what has happened is my son was in my lib dot dll not in my main dot Yeah, CSI not in there. So main dxy now depended on that file on because we've deleted it. We can no longer run the program because main Dottie XY is not aware of my son My son was stored in my lib dll So that's what makes them different to object files with object fouls waken. But we compile all the object files to make a program so main what main dxy would contain? Um, all of the symbols and needed, including my son, But because this is the libraries different. What we said waas is when we compiled it with sheds, we basically said create a shared library, a dynamic dynamic link library Andi store store store are symbols in there. And then what we wanted Compiled main dot c. We provided my lived a dll which is telling the compiler that this program depends on this on this library. On that you can resolve symbols there. So now we need mate mileage. Dottie allowed to run this program because my lived up dll holds my son and not main. Don't yet see main dxy does not hold my son. So I hope that explains libraries essentially in like a game project. You would have all sorts of graphic libraries dynamic link libraries. So the whole point of libraries is basically just to extend functionality for different projects, allow them to reuse code written by another developer compiled code. So that is how it works. However, just a further explain that thes two separate things my lib on main. What we can do is we can change. We can keep the main file the same and we're not going to re compile it, by the way. But we will change my lived at C. Let's put a plus five by Here is well, so my son will now some a and B together and a lad plus five as well. Now, if we we composite again gcc my lib dot c Dachau my lip dot dll dash ed press enter. And now do you mean again? It gives us 15 Now, we haven't changed the code of maine dot c at all. We haven't re compiled our main dot See, the excusable has not changed. But we did re compile our library on now. Know it's how the value is different. So that proves that my some is in my lib on that it is not compiled into maine dot dxy. 32. Goto Keyword: So we're now going to discuss the go to key word. What the go to key would allow you to do it allows you to jump to different sections of your code. You need to be very careful when using the go to key would because it can be abused on lead you to bad practices. So what we can do is we can go out Colon here when we could do a turn zero. Right now, what I can say is, um if one So if true which in low would be true, by the way, go to out. So this if statement will run and then we jumped out and I'm here If I do Prince f, we're leaving now. If I can pilot now, GCC main, don't see Dachau main run that it says were leaving. So what happens is I enter this if statement and I immediately jump to this out label skipping all the code after here. So just to demonstrate that if I go, this is never called while happen, is we entire If statement because one is always true, we go toe out, which will skip over all of this on go to this label here on begin running from there. So if we can pilot now run that All we see is we're leaving because we jump over this. If we put a zero here, so it never gets run. Ca zero is false and we we compile that GCC main dot c Dachau main and then we do make this is never called, is now shown on. Then we're leaving. So that is labels on the go to key. Would the's air quite useful and see, because in See, you're in charge of managing your own memory, which will get too soon. And it's very important that if we if we were to return from here, then we we would never d allocate our memory further down here cause we returns from the function. So by using go to weaken, jumped to the out label and then free the memory and resource is here, but more on that later. But basically, that's why go to is useful in C in C plus plus, you should probably avoid go to, but in C, it's it's pretty useful 33. Memory Allocation And Stack Vs Heap: So we're now going to discuss memory in C. Now. Currently, we've been dealing with variables on the stack. Essentially, when you declare a variable here it is on the stack on. The problem with Stack memories is very limited, but it's also quicker to create than heap memory, which we're about to discuss now. So what is heat memory? The operating system has a He has what's known as a heap, which is basically an extremely large amount of data, and we can ask the operating system to access that data. So we consider the operating system. I want 1024 bytes of data. Can you please give it to me? It'll then respond with zero. If it won't, that means something went wrong or it will respond with a pointer toe that data that it's just allocated for you. So, for example, if I'm loading a movie file there's 200 megabytes in size. I could say to the operating system, Please give me Children megabytes of data. The operating system could then respond with a pointer to that data on. Then I can then access that data as if I allocated it here like this see, we create way creating a ray here with 1024 bites. While I could ask the operating system for 1024 bites on it will give that to me as well. So the difference here is stack memory. This is stacked memory. Right now it is limited in size. That is, the cons the pros are is quicker than asking the operating system for memory. Okay, so let's begin less first include sed lipped our page which will give us access to the memory functions we need. I now need you to do char ask Chris PTR equals Malek 1024. So you can see here Malik returns a void pointer and it takes the size. The size is how much data we want for them, how many bites we want from them. So by doing 1024 were basically requests in the operating system for 1024 bytes of data. First to use now because it's a void pointer. We need to cast this into a char pointed because we want to access. This is a chart. So we do char ask risk right there. As you learned in the casting tutorial. So we now for semi colon there and we should bear to do 0.20 equals a point. A one equals B and I should be a day now. I'll put that like this. So we output 0.0 less now compile that GCC main dot c Dachau May Onda We should si a which we do now. If you put one here, we should see B which we dio so we can safely access 1024 bites. If we go over, that will crash our program because we've only asked the operating system for 1024 bites we tried to access and a new index that takes us out of those bounds. The program will crash a best or undefined behaviour at worst. So that is how you can allocate memory on the heap. And it's very useful now. There's one problem with this. We need to free this data when we're done. So you do that by doing free PTR this simple. Is that so? What? This does this allocates 1024 bites from the operating system. We now have access to that data. So we said the first index to a the second index to be we output a uh, we'll put Be sorry, point of one. And now we tell the operating system with free that we're done with this memory. Now we don't need it anymore. Recycle it and give it to another program that might need it. That's what we're basically saying. Here, without this, you have what is known as a memory leak. Memory leak is where you ask the offering system for data, but never give it back. Have you ever had a program that gets really, really slow over time? While a lot of time? This is because of memory leaks. You have programs run in that are not free and memory. They've asked for on this Kenly lead to the a slower computer that is running those programs because you never give the data back to the operating system, even if you don't need the data anymore. If you don't need the data anymore, you should pass the data back to the operating system by doing free PTR it then can give that data to someone else who needs it. So that is basically how you allocate memory on the heap. This could also be in churches. So I could do something like in Georgia. Pointer cast that inch and then I can use the size off key word which gives us the size of a type. So if we do size of in it, it will return for on this is executed a compile time. By the way. So the compiler will replace this with four as its compiling. So if we can pilot now, may we see nothing? Because I haven't output it. But now if we do print f all right, and then we do ask risk PTR. Remember, we used asterisks to say we want the value of what? Last pointing at If we now run that again we see 6886808 Now why do we see that? Because we haven't set the memory if you don't set the memory is basically a load of garbage or whatever was left in memory from the last person who used it. So to do that we do pointer, ask risk. PTL equals 50. And after you now compile that again we see 50 so you can see my lock could basically get you any amount of size of data and then you have appointed that you can access however you want 34. Memory Functions: Hello and welcome guys. We're now going to discuss memory functions in C so first include the memory dot page header file on this will give us access to the memory functions in C. So I want you to make a sharp buffer with a char ray with 20 bites and then I want you to go print af percent c on. Then do your next argument on do buff zero. So this allow put the first value in the buffer. But we haven't set the buffet anything. So what's gonna happen? Well, it's going toe output the memory. Anyway, By doing this, it adjusts the sack. Bona given us 20 bytes to use in the stack, right? But that memories in an un initialized state, which means it could be anything we need to actually set that memory, Which is why I'm discussing memory functions now. So if we go to clamp from just going, showed that show you this do gcc main dot c. Dachau may run that. You see a plus. Now we didn't put a plus in there. That's just happens to be the data that that is there when we run that it could be anything it could be. What? Whatever was used on in that stack memory last before us. You know, the see you calling a few functions. It could be data left over in the stack from another function. Call is Isn't is in an un initialized state, which makes it dangerous to use. So what you can do, you can change this memory. So men set buff zero sighs off, buff. So what is this to them? Well, they sets the entire array 20 so I will go index zero equals zero index. One equals zero and so on until the entire array is set to zero. So this size off. As I said, it returns the size of elements at at compile time. So during compile a shin, this is replaced with 20. Right? So what's gonna happen here? Um sighs off, gets the size of our array, which is 20 bites on. Then we set the entire thing to zero. That is what is happening. So if we now compile that again, we can see nothing because zero is a no Terminator. Remember I said that if you want to change this Teoh quote A because this is This is for one bite at a time, right? And if we then compile that we see a on this entire array is now a So if we do buffer five , we see a so men said is great for initializing arrays. Basically, sending them all to zero is a common practice mainly for safety, especially when our load loading in strings here. Because if annul Terminator is an included, then on you go to print out their message, then you're gonna overflow the buffer, right, because your print f when you packed like if I do print f s on bypass in the buffer here, it's going to try and read the entire buffer until it finds a zero, which is a null terminated, which tells the programme that string has ended. But if there's no zero in here until the end of the buffer, we're gonna overflow it on just to demonstrate that if we put in a here now, so percent s will output. The buffer is a string. What percent s says is go through the buffer until we find a decimal zero. Remember the asking table, not a number zero a decimal zero on actual binary 08 zeros in binary when it finds that it will stop, uh, trying to output string because the strings ended. Right? But because we haven't provided a null terminated here because we've set our entire buffed to a right, it will never end. So if we try that now, you can see it does output are Ray, but I'll put some other data as well. That's because it has. That's because it overflows are buffer for a few bites until it sees a zero but the zeros outside of our buffet. So we a sense you ever buffer overflow there. So if we was to do something like But for 19 which is the last bite of our rate, by the way, equals zero x 00 which is hacks decimal zero. You could even do decimal zero if you want it. That's fine. Equals zero. If you compile it now. Now I only outputs the data it was supposed to because we set the last bite of our buffer to a decimal zero right by here on line eight. So that is some useful advice. So there's some other functions I want to show you. There's a men copy, which is quite an impressive function. So before we do anything further, let's set this to zero again. Okay? Now, what I want you to do is I wanted to do men men copy on the destination is gonna be Buf. The source is gonna be Hello. Well, it's just gonna provide the string right there on the size is gonna be How many bites is that? 12345 Fight bites. So what, this does this copies hello into our buffer on a copies? Five bites. So now let's explain this a little further. Remember I said that when you provide strings like this when it gets compiled, it puts this elsewhere in your program. On this becomes a pointer. This becomes a value to a value to the address. So that's important to note that, right? So if we now compel this on we go, May you see Hello. So what, this does it copies hello into our buffer here. Nice handy feature. So let's try and be a little more clever about this than, um at the top here less Kochar. Uh, my message equals hello world. And now we're going to go my message on. I'm gonna cause a problem on purpose. So you can see this. I'm going to go size off my message. Andi, what we're now going to do, we're gonna compel it again. On what's this? We can only see Hell, it doesn't say hello, world. Well, this is indeed help. Because if you ever made this mistake and I'm showing you this because it is a common beginner's mistake sighs off. We're using size off on the my message variable. But you're forgetting that size office calculator compile time. And secondly, my message is a pointer. It is not Hello world. It points to hello world. So my message is appointed, guys. So a pointer is four bites so size off returns for so we only see help. Now what you can do is str Lynn, which is a function in si I would just pass my message there. So what this will do? This will get the length of this string. How does it do that? It goes through every single bite until it finds Arnold Terminator. And remember what I said When you do these double quotes a compile time, it automatically puts the null Terminator in for you when? When it creates your txt file. So if we now run that again, you can see Hello World. So that worked perfectly. So what's happening here? We set our entire buffer to zero. We copy my message into our buffet. On my message is a pointer pointing to the address of Hello World because remember, Hello World is and stored here. It's stored somewhere in our program as a series of bites. On this, a compile time is replaced with the value to the address. So we copy Hello world into our buffer. We output it so that's that's how you copy memory. So now let me discuss memory compare functions. So the memory compare function allows you to compare two pieces of memory and see how close they are to a match or if they do match. So let's not do that then. So what I want to do is I want you to go in Chur. Results equals men. Compare M e m c M P. Now ask for buffer one in buffer to So let's just do hello world and then do Hello World here is well, make sure that the same guy so I can demonstrate this, uh and now just do s t l n Hello? Won't. Okay, so well, that's gonna do. That's going to compare the hello world memory with hello world on its the length of hello world. So compare all of that and it should be zero. But anyway, let's test that a 2nd 1% I here and put resulting here Unless compel that and you can see zero. So men compare function. It returns zero if the two pieces of memory match. So this is the first address. This is the second address and this is the length that we're gonna be compared. Okay, so you now know that men can't men compared return zero when they both match. Now what if they differ? Well, let's try that, shall we? I want to put a by here, and I wanted to put a beat by here. And then I want you to compel that I'm run that and you see a minus one. Now the reason you see a minus one is because what the men compare function does the first byte that does not match it checks to see which one is greater the one in point of one or the one in pointed to Andi. It returned minus one here because be has a greater decimal value than a Because if you remember the asking table, you have decimal numbers and in characters next to it. Well, if you look at the asking table, you'll see a is before B uh, the decimal equivalent, the binary. So a and B our differ on because B is greater than a we get a minus one returned. Now, if you change this to see, but keep, this is Bello. And if you then Kampala you see one. So then that has the opposite effect. Because C is greater than be so returns one. So once again if they match returned zero. So I just wrote this coat quickly just to demonstrate this a little further. Here we say If the buffer on my message match like the values match the values there pointing at matches based on this land, then output they match. So essentially because Buffett has hello world because we copied it here online nine on my message has hello, world. Then they are both a match so that so it will output This message without men copy here. It will not help put it because buff no longer contains hello world. 35. Reading And Writing Files: Hello and welcome back. We're now going to discuss how to read and write files. Firstly, make sure you include STD ioo dot page on memory dot page. Okay, So what we're gonna do, then, is I want you to do file f equals f open dot Ford's last test up. Txt on This is the following. We want to open on the second. The second parameter is the mode. So this could be like opening the foul for writing, opening the foul for a pending or open and foul for reading. So here we go, which means we're opening this fall for reading. Andi, if you now do if f on inside here doing explanation mark just before the f and then do print F failed to open file return minus one Now, while this will do is if it first opened the file for reading, it'll output this message and leave. So if we know, compile that GCC main dot C Dachau main run that you can see fail to open file. And that's because test optics T does not exist in the directory that this excusable is run because remember dot forward slash means This directory means the current directory. So in our case, it will be the current directory Main Dxy is being running. Um, so if we now create a new file here, I call it test on txt enough. We type hello world in here and we now compile it again and run that you can see we see no error message because it managed to open the file. So down here just to f close f on what this does is it closes the file. So that is just to close the file handle. Basically, when you finish with the file, you close it. So we're now going to read from the file. So first sailing to create a buffer, call it sharp buff and put 20 in here for 20 bites. We're going to go meme set buff, zero size of buff. So this will set our entire array to zero. Um, because when we re from foul, we want there to be a null terminated at the end. Right. So here. Now, I want you to go f freed. I wanted a passing buf a buff, and this is the element size. So f read reads in blocks. So, for example, if we put 20 for the elements size on put, I don't know. 30 for the element count. It'll read 30 elements in 20 byte blocks. So read 20 bites, and then that's one. That's one element in Louise. Another 20 bites. That's two elements on every returns, the number of elements red. So, for example, if you haven't element size of 20 on an element kind of one way read 20 bites, but one is returned because the block size is 20. All the elements sizes 20. So, what we're gonna do in here, we're gonna put the elements sizes one because we want to read one bite at a time and we're gonna put, uh, we're gonna put 20 by here. And then finally, here goes our fall stream are open files we put f. And now, if you know, check to see if this is equal to zero on. If it is, we read nothing. There was a problem. Okay? And now you can return minus one here. So now we should be able to just print out our buffer here. So if you do print F percent s, which means that we are out putting a strength. So will happen is print. F will go through our buff. It allow. Put every single character until it finds Arnold Terminator on. Then it will stop. So let's no compile that and we run that we see Hello world. So it's red Hello, wolf from our file into the into this buffer here and then it's out. Put it now let's take a look at the result off, eh? Freed. So if we go interject results equals f read and into that And here we just to result equals equals zero show the era And now in here If we output underneath here we go Firstly put a backslash end here for a new line If we then go print f percent I and then we do results And now we now compile that again I'm run that you'll see the outputs 12 which is the size of hello world because it read 12 elements. So if you're expecting a certain a certain sides to be read then you could also check here that it it is equal to that. And if it is not equal to that, you know if it doesn't equal 12 If it does not equal 12. Then we failed to read the full string that we wanted, for example, but equals equals zero is sufficient for now. So let's change the size here to to So that elements sizes too. If we now compile, um in that we can see hello world, but that the result returned from Jeffrey to six because it read six elements because it was reading two bites at the time. So I hope that makes sense. If we put in 12 years, so reads the full thing on. We want to read 20 blocks of 12 so it will attempt to read. It will attempt to return from 40 bites. Then what will happen is that we run that now Compile it first. We now see one because it's red one block because it's read the full 12 bytes, which was one block. We have 13 here and we can pilot. Now you can see problem reading from file because 13 was the minimum matter bites I had to read and it couldn't finish reading that block. So there was a problem. So it returns zero because it couldn't read the four block because remember the result that every returns is the amount of blocks read on because our block size is 13 and we only have 12 bytes in the file. It couldn't read the full block, so it read zero blocks. I hope that makes sense with F read. So we're now going to discuss how you can write to files. So let's get rid of all of this. And I want to change this mode here to W on what w means. It means we want to open this file for writing. If the file exists, overwrite it. That's what that means. So now if we now do f writes and we did, um, hello roads and in our element size waas one. Because we we want to read we want to write one bite at a time And then the element count is the size of hello world. I mean string length Hello, world string land Hello world. And then here we do f for file. If we now run that it will write hello world to our file. But let's just to hello world. How are you instead and make sure you change. This is well, guys because it needs it needs to be able to write the full amount. Right? So now if we now compile that again on run there you can see we see no message. But if you now go to test up txt you see Hello world. How are you? So we've essentially wrote to the file and again this works like f read. It will return the number of blocks. Read the number of elements red. In our case, the element size is one on our element. Count is the size is the string size of Hello world. How are you? So that is how you can write files. Let's now discuss how you can append files. So if you change this flag, heat this mode here to a that that means append. So if we now compile, um, run that again. You can see nothing shown But if we go back to the file, you know see Hello world. How are you? Hello would hire you if you run in the third time on, we reopen that again. You can see it again. And if we keep running it it just keeps upending the file on another another. So that is what the appends for its for a pending files w overwrites The file. A pen depends to the end of the file, so another thing to discuss where penned is it doesn't create the file if it does not exist . So let's now discuss our plus. Ah plus opens the fall from reading and writing, but it does not create file. If it doesn't exist, W plus creates the file. If it doesn't exist, it will open it for reading and writing. A plus opens the foul for a pending and reading. 36. Const Explained: So we're now going to explain what Constance Const allows you to set a variable is read only. It should be noted that this is a compile time. Only thing essentially at runtime you can still change the memory. It isn't protected at the process of level in any way. If I now do Constance, Ginger A equals 50 and I compile that you can see that works. Fine. Find out. Do eight was 20 beneath here. Compile that error assignment of Read only variable A. So we actually can't assign them. Now if I wants to go sharp off 20 and then I did Char PTR equals buff. That would work fine. Five ended 0.0 equals 50. That would work fine too. We compile that. There's no problem if I now change this to Const are Pointer and I cast this to conserve char pointer And now I compile it era assignment of read only location so we can no longer a sign that But if I did hear buff zero equals a buff one equals b Andi, I get rid of this and I did print. If I I mean see, do you see 0.20 this will work fine, so you can see if we run that we see a So the reason we can do this is because buff is not constant. However, the point of the buff is constant, so we can read it through the point of. But we can't assign it that it's not allowed. So that's what Constance is a way of making variables read only. 37. Static Functions Explained: Okay, guys. So we are going to discuss what static functions are Static functions is a way of making a function only available to the source file. It's in. So to demonstrate this, let's first create a new file called Test on C on. We're gonna have insurgent my some into a insta be on. We're just going to return a plus B and so we don't have to create ahead of file. Let's copy this and we're gonna paste it up here once again. Just so it is just so may not see is aware that my some exist somewhere. I know what I now want you to do. Instrument Sult equals my son. 5 10 and we're going to go print If I fought back session result. So this so print the result, which is 15 Because my son will add those two together. Andi. Then we output the result, which is 50. If you now compile that now. Well, first compile test artsy GCC test Artsy Dachau test. Uh oh Dash c for object Far on now. Do GCC main dot c test R o uh, Dachau main if you know one main. You see 15 now go into test out, see on put static at the beginning of here. That's all I wanted to do and they re compile Test at sea. Re compile main dot c and you can see undefined reference to my son. Now, this is because my some ecstatic, which means that it will not be compiled into the object far The object file won't have a reference to explain that my son is here so main dot c What? Even though we link, it would test our Oh, it cannot resolve the my some symbol. So by using static, we make it only available in test Nazi. 38. Bitwise Operators And Bit Shifting: Hey, guys. So we're now going to discuss what bit operations are in C But to really understand that, we first need to understand what but operations are. So essentially you're process has a bunch of instructions to perform operations at the bet level. Andi, there's a bit wise and a bit ways orbit wise, Excell and so on. But let's now explain this. We're going to start with bit wise. And so I wanted to select the binary here. This is a calculator at easy online converter dot com. It's the bit wise calculator. You don't have to do this. Just follow. What I'm doing followed the video. So you understand. So in number one, I'm gonna enter eight bits and they're all gonna be ones. 12341234 And in number two, I'm going to do the same. 12341234 And I'm gonna make sure the bit wise operator and is selected. I'm gonna press calculate so we can see the results. Is eight bits on that all equal the one. So what happens is the process of checks. The first number you entered the first bit and then it compares it to the next pit on the second number. If they are both won, the output for that bit is one. And then it goes to the second bit. Is this one? Yes. Is this one? Yes. Okay, so that it is one and this is how it calculates the result. If we put a zero here, I'm press calculate. We see 1111 11101 on. The reason for that is because this bit is one. This spit is zero. So it doesn't set of satisfied and the and operator and therefore this bit in the result of zero. So that is how and works. So essentially, if he's a role zeros 12341234 And we press calculate, the result is zero because it goes through each individual bid, it checks this one against this one. It checks this one against this one, and the bit in the result is only one. If both the bets in number one and number two are also one, and that's binary. But you know, decimal works the same year. We can put 255 here in 254 Here, press calculate when we get to 54 2 50 calculate to 50 to 10 and then we get to 10. So it works the same because remember, everything's just binary and decimal is just a way of expressing that binary. So we're now going to do this in the code. So I wanted to go and Sanchar a equals zero B for binary 12341234 Unsigned sharp B equals zero B 12341234 And then we're gonna go and sign shar results equals a m person. Be notice how I only use one n percent here. This does a bit wise. And on these two numbers, if we now compile that GCC main dot C. Dachau May May on we see nothing, cause I haven't output it. But if we do print f I four slash in our results and we can Paul that now we now see 255 because the processes checks this one it says yes, this is one. This is one too. So this bit and the result is one this bit is one. This bid is one too, so that but it in the result is one. So we end up with decimal 255 which is thistles, the binary equivalent of decimal 255 on bit wise, and is great for checking if a flag of some kind is set. For example, if I grew up here and I do define, uh, I don't know, special flag and I do zero b 12341234 And I gave it to the final zero. Put a one. And if I now do and I give it to this if I now do, if a on and special flag what will happen is if are a variable If the final one here If they variable also has a final one, then this If statement will be run flag set. So if we now compatible app, we can see flag set. However, if we don't have that flag, we put a zero here. We see nothing. So by using that the and operator the ambit wise operator, we can have up to eight flags per bite. So I don't know if you're making a program. This special flag could maybe represent that The file, the file format your reading is, I don't know is read only or something. So this is incredibly good because it means that one you store when you store char A in the file, it can represent eight different states that are different flags. So I could literally have a lesson designing a file format. I could have a bite in the file the represents attributes of this special file format that we're making and then you can see that this special flag, if this final bit here is set in the file, then you know that they special flag set on weaken do whatever that special flag was supposed to do. So essentially, without this, we would have to store eight characters. So eight bytes in the file to represent each of the eight flags, whereas by using bit wise operators, we only one bite and we can have each individual bit represent a flag. So back to this calculator less. Now it select binary again. Unless now explain the orbit wise operator. So if I do 12341234 12341234 And now I now press for on I press calculate I can see the result is equal toe both of those numbers. Now let's change on a binary digit 20 Doesn't matter which one we now press calculate we still see our original result on the reason for that is because bit wise or it checks the bid against this bit. And if either one of them is one than the resulting bid is one. So if these are both zero and I press calculate, we see that But if this 10 here but this one here is still one, then we still see the same number. If I now change this 1 to 0 press calculate, we now see zero. So once again, the process of checks that this number here is one All this number is one. And if either one if either of those is one than that, resulting bit is also one. So let's now use our bit wise or in our program so firstly giver to this, if statement on put a zero here instead of a one. So this is decimal 254 which can be seen by doing this If we now compel that we can see that this binary number is equivalent to 255 4 decimal. So what if we want to set our special flag in a while? A bit wise or operating is great. For that. We can literally go a equals a special flag. So you use this little line to represent the bit wise or so. If we can pilot now, we can see 255 So what's happened is it's done a bit wise or on a on our special flag. So the process has gone through and it said, Okay, we see a zero here on our special flag. Um, is there one in a Yes, there is. So this resulting bit is one, and it does the same. Here. Is this one? No, it isn't. Is this one? Yes, it is. And this goes on and on until our final bid. Andi were a final bit. Now on we say, Is this one? Yes, it is. Is this one? No, it isn't. But because this is a bit wise or on, this is one than the final result in bit. Must be one on that equals to 255 decimal. So that is how you can do the bit wise. All in C. I should also mention you can also append it like this or equals. So that says, What? Changing variable a onda We're gonna do a bit wise or on our special flag, so that basically the same saying a equals a bit wise or special flag. It's exactly the same, much like you can do, plus equals or minor Sequels when you're dealing with normal numbers and not bit wise operations that we're now going to discuss. Bit wise. Xar. Now what X Or does if the bits is not equal to the other one than the result is one? So, for example, if all of these was zeros 123412348 zeros, we press calculate, we see all ones. If this one is changed to one, we see this one's become zero because both of those are one. If this one become zero, we can see this one become zero because this bit on this bit are zero. So that's what X or is. So I've created to Charles here to represent thes binary numbers on We're gonna perform an ax or on them. So go and sign Shaw. Results equals a be. So just use this little arrow character here to represent that. And that is our ex operator. So I can Now I put the results and we should see decimal one, which we do. We see decimal one. So what happens is our results is equal. 20 b 12341234 Garroted finals. He would put a one on the end. So 1234567 zeros and a one on the end in binary. That's what is equal to on this finery. Number is equivalent to decimal one. So that is basically the X or inaction. So what's happening is it's going here. Is this one? Yes. Is this one? Yes. Okay, because they're both the same. That zero so and a zero goes there and it does there seven times and it comes to our final bid and it says, Is this the same as the one and be? No, it isn't. So the result must be a one. So that is basically the bit wise. Excell, Let's now discuss bit wise, not so all a bit wise? Not does is it basically flips the beds. So if we did 12341234 and we pressed Compute! We get zeros if we did. 123 for 1234 We get 00001111 So, basically the bitten if the bits one become zero if the bed Syria becomes one on this is done on one operate and there isn't too like there is with all the other operators I've just shown. So that is basically bit wise. Not so. I'm now going to show you how it's perform of it wise, not in C. All we do is a scared of this. We go, a unsigned Shaw results equals and in this little swirly character on a that's all it does . So this will flip the bits so the result will be equal to 12341231 That's what the result will be equal to. It affect the bits. Eso we should see decimal one out. Put it here. Let's try that. Compile a and we see decimal one. So that's your bit wise. Not Let's now explain bit shifting. So essentially you can shift bits to the left or to the right, and that's pretty cool. So let me show you how to do that. All we do is we say result equals a and we do, too. Left errors zero p. 12341234 Put a one at the end there. What that says is shift a one to the left. That's what I says. So if we now compile that, you can see to fight, too, do that 248 So this shifts the bits to the left. That's basically what's happening here. And you can also shift to the right by doing to write house Kampala 63. So that is bit shifting. It basically allows you to shift the bits to the left or to the right. So I expressed. This is binary, but you can use one here is well, so this means shift one bit to the right. This means shift one bit to the left. So let me show you how to do that with the bit wise shift calculator online Just so just so you can instead, a bit more So we have four ones here. Eight ones here we have and we want to shift one to the left. So press shift, we can see the binary is now. 123456789 It's now nine bits in length because we shifted one to the left. But in the process, it doesn't quite work like that. If you if you overflow the register size basically the size, the maximum size. What? You can store the data, then that is discarded. So all we would see is thes that I've selected here. So essentially by by shifting all of that to the left by one, we actually end up with zero as our first bed. Here on that is what happens because we've shifted it and the final bits just carded. If you shift to the right, then you'll notice we have 1234567 only seven bits now. So likewise, there would be a zero here that you can't see on this calculator. But that's how would look so if I just get a note pad quickly. It would be that so by shifting to the right by one, we lose our final bit here at the top. On that come zero 39. Argc And Argv: All right, let s discuss Oxy Analogue V. So these two variables combined describe information passed to you When the program starts . Now, Oxi will contain the following of this excusable. That's the first thing that contains. And then anything else after that is options and values passed through our program just before it runs. Now, I know this might seem a bit confusing to you, but just bear with me and follow what I'm doing, and it will all make sense. So what we're first going to do is we're gonna say if Oxy equals one print f no arguments provided Return minus one. And I we're now going to go four inches. I equals zero I below Oxy I plus plus so nice followed print F R V I, and you also need to put the percent s for backslash end by here as well. So the coach should like that. It's pretty straightforward. You're a bit confused now, but as soon as we run this, you'll understand. I promise. Compile that with GCC main dot C Dachau main run made you see no arguments provided. Okay, so then type main. Hello? Now what? You see that you see May now put it and you see Hello. Some main is three excusable that we have running and hello is the second argument. So essentially what happens is main Hello, How are you? You can see after each space is a separate argument. So essentially, what's happening is what we call main. Here we start our program. However, everything we pass in here is passed to our program and it's passed to us through Oxy. An R V on each space in this command represents a separate option. So our CSI is the number of arguments past. So in this case is 12345 on RV contains the actual character data such as Hello, How are you, Senior? You can also do things like this. Double quotes and then it's seen as one argument. So that is how you from past arguments to your program on be able to process those options passed to it. So the reason why this is good is is someone might want to pass a file name in here, uh, for you to process. And then you know that OG one contains that falling because odd vys zero is the main the extra skittle name. I hope that really sums it up. Um, but if you have any questions, send me a message. 40. Seeking In Files: welcome. So we're now going to explain how to seek in files. So the first thing I wanted to do is include STD lip pedophile to give us access to the foul functions on what seeking allows you to do in a file. It allows you to seek to a position in the foul and start reading from there. So it's very good for seeking through large fouls that might be gigabytes in size, for example. So once you've done this, I want you to create a new file here, and we're gonna call it test on txt. And I just want you to type a bunch of data. Let's make sure is a little long. They are mines. Nearly 2000 characters. Now, I'm backed arming function. We're gonna open this file for reading, so I want you to do file asterisk file equals f open. And then I wanted to say, Don't forward slash txt on the motor be read. So this a load test start txt from the from the local directory. Now, I want you to do f seek, and it's gonna ask you for a stream on an offset type and file for the stream offset. Let's say 20 bites on the origin will be seek. Seek current. So if we now go chop off 20. And we do, eh? Freed, buff. On we go one on 20 here and then we should be able to do we should be able to output are buffer from where we seek to But before we do that, what I want you to do I want you to do, uh, both just before this Sorry. I wanted to do Buff 19 equals zero. So this adds Arnold Terminator because we're reading data from the file here, but because we're only reading a certain amount of data, the null terminated which ends the string is not included because the know Terminator is away at the end of the file. So if we now do print F percent s buff on, we can problem run that with GCC main dot c Dachau main. I'm we run that. We can see. Ah, string. Now this is offset it 20 bites into the file. So essentially here. When we do f seek, we're changing our current reposition in the file on. We're putting it 20 bytes ahead of our current position. That's what seeks EU are means so essentially, by using f seek, we can reposition where the file is pointing. So in our case, we say 20 bites from our current position so you can use seek set to go from the beginning of the file for you sick seek set than it accounts from the beginning of the foul. So in this case, it will be the beginning of the foul plus 20. Whereas if you use seek, see you off a current position, then let's say we're we were already opposition 20 in the file. This would then take us another 20 bytes ahead. Okay, I'm now going to show you how you can use foul seeking to determine a file size. So if we get rid of all of this and we did f seek file on, I want you to do zero here, seek end. So that's oppositionists at the end of our file on now to get the position, we just to f toe fire. And now, if I haven't, this is an unsigned long. So if I go unsigned, long passed secrets FTL file. Now, this will give me the size of the file, but Obviously, you probably want to go back to the start of the stream so that you can start reading from the beginning, right? So to go back, you just to f seek file zero seek set, and that will bring you back to the start of the foul. So if we now do this, it should give us the size of our file. And if we re compile that, now we see 1000 changes and five, which is the size of of our file on. Obviously this it This is named pass because it's the position of the end of the file, right? So you could call this file size if you wanted. I'm Maybe that's a bit more clear. So that's how you can seek in the file and move your position of where the reading right? Heads up. 41. Switches: Hello and welcome. So we're now going to discuss switches. So a switch is like an if an if statement on NFL statement, but it's a tiny way of doing it. A new switches when you have lots of different options s A rather than having a massive if statement switches a much cleaner. So let me show you how to create a switch. First thing we need a value to compare against. So let's go into the results equals zero and I wanted to do switch result on then what you can do is you can go case zero break case one break case two Great. And now you can go print f k sirrah print if case one and so on. So on on what this does It basically says if the result is zero run this code here if the result is one run this coat here if the result is too run this code here now thes these cases are not separate scopes. What I mean by that is if you wanted to go into a here, you couldn't do in Shea here. I I want to make that very clear. If we can pilot now you can see there's a problem right now. The way you get around that is, you just use Curly's because these curly's races, these curly braces, can actually be used outside of all statements. It could be like that on because they're two separate things. You need to know this. So here we say, create a new scope where I can define variables inside. You see that is legal. If I do into be and should be, that is legal on. If I didn't have these, then it's not legal, right, because then we define in stripy. We re declare it twice Well, it's important to mention that because the same applies here, these cases are not separate scopes. So if you want to declare variables in them, you you should use these curly braces. Now, let me explain a little more about what's going on here, so cases are basically run if the result is equal to the case. So if it's if the results zero k zero is run, which will output Casero if case one if result is equal, the one in case one is run if result his case to in Case two is run so Let's just run that quickly on. I'm just going to give it to this interest your that I put here as well. If we do main weaken CIA says Casero, you set result toe one you can see case one. If you set result to five, you'll notice you see nothing. So how do we do in else in a in a switch where you can use to felt print F, nothing selected. So what this does if I run that now? Nothing selected. So if the result is not case zero, it's not Case one. It's not case to then output. Nothing selected. That's what default is for. Default is basically an else. If none of the cases can match, go to default. So there's another clever thing you can do with cases here. You can have multiple cases run the same coat now to demonstrate this is important to understand. Break now, much like in our in our statements lecture. If statements are sorry, four statements and on wall loops you can break from. If you remember, break leaves the loop early, while similarly you can break from switches as well. On all a break means is undone with this switch. That's all it means. So I happens. Is we come into Casero? Here we are Poor Casero, we break on Essentially Leave the switch now without break you What happened is it would run Casero, in case one if you know, compel that Onda also we need to change our results. Zero guys change a result zero You can see Casey Your case one Now If this is one compound that again you only see Case one. So let me explain. This one result is Case zero which it is now What happens is the actual code comes in here . It jumps to hear Casero get outputs, Casero And then because there's no break leaving this case it then runs onto Case one I'm runs case one and then finally against the brake on leaves on. That is why when we do Casero, we see KCIA in case one. But if we do case one, we only see case one because we don't see case to Because we break here on case one After you got rid of this break so that it's Casey or case one case too If you now compile that you now see Casey a case One case coat too, if you set result toe one. You see, case one case to you said it to two. And you'll only see case too. So that makes sense. In other words, the coaches keeps running down until it sees a break on. This is great because it allows you to kind of combine cases together, which is pretty helpful. So another thing we can do before this tutorial ends, I can show you another thing. Get a case one on. We're gonna call Casero and case one. That's that's what we're going to rename that to put a break here as well. Guys are now just in the case. Zero to case one. So you can also do it like this. So all this means is, if it's case zero, then carry on running down onto case one and output this message on if its case one then carry on, running down on output. This message. So now if you put zero or one as the results, you can see Casero in case one. If you for one is the result, you can see case you in case one. So that is basically switches on their amazing for comparing results like this. So a final thing to know about switches. Your cases have to be constant values. In other words, I can't point this to a variable if I do this and I want to see if a is equal, the one I can't do case A. That does not work. You have to use constant values now. If you had a definition of the case value, that would be fine. Because remember, that's done at compile time. So if I did define case, one equals one, and then in case when I changed it to case one, that would work fine. Because remember, the pre process of the compiler replaces this with one during compel time because case one is equal to one. 42. Simple Book Program Part 1: so using everything you've learned in this course, we're now going to create a simple book program that allows people to Agnew books to the program Onda Pull, Pull Which books are already created. Now we're gonna need a hacks, a decimal editor to do this because we're gonna be storing binary in our file on binary characters cannot be displayed in a text editor correctly, which means that we cannot use the text ed to examine our file for me to explain it to you . So we need a download. Hex editor Neo severe Open Firefox, I think Google type hex at its own neo download. And just you hasty d software dot com here on press download and then openly installer on just press install. And now it will say launch hexes. Tonio, just press clothes on, hex it in Estonia. Well, Loht just press continue and okay. And this is our hex editor. So now that we have hex Editor neo installed, now we can finally begin the coding. So include the STD lip had to file, which will give us access to the foul functionality. And now I wanted to create a new file here. I just call it Data Dobbin on dup been is just on extension on. We're calling it up in for binary. It could be named anything. Really? So we're now going to go file asterisk on. We're going to go f equals f open. Don't force. I stated up in and in here. I want you to do R B Plus Now I know we didn't discuss ob e yet. Essentially, with your mode, all you have to do is put a B after it on what this will do. It will open the file knowing that it's a binary file. If you don't do that, it will open it as if it's a text file. And there's certain characters in the text file that the functions will interpret differently. Whereas if you do RB, that means this is a binary file. Don't do anything special. That might make it difficult for us to read this because in text value of new lines and all that sort of stuff and the functions are provided and see can handle those on you don't really want there for by nearly fell, so use RB and plus here, so that will open this file for reading and writing. And we can now say if ask risk F failed to open file return minus one and then he had just you return zero. If you now compile that, we see nothing. Which means that it worked successfully. If you don't have dated up being, if you didn't create it, then you'll see that it said failed to open file guys to make sure you create that first. So where are booked Program is going to Starbucks, so bucks are going to be a structure. So let's make a struck cold book, Um, are books gonna have a title which will be 20 characters? It is going toe, have a description, which is gonna be 200 characters, and we also want to flag that determines if it's sold or not. But we can get to that later. Let's keep it simple for now. So title and description, that is all we want to deal with right now. So our program is gonna have a few modes. But before we continue, I want you to copy our file pointer here, place with F and just paste it up here because we're going to be making some more function soon. And we want to be a to access that file. Right? So let's create a new function called, um void. No introgen handle creates, that's all. I when you do, and what we're now going to do is we're gonna ask the use of some options of what they want to do. But to keep the coat clean, we should also move this into its own function. So copy that, and we're going to go avoid interject, um, set up file. That's all we're going to do. And I wanted to place that in there. So that is going to be responsible for setting our father basically loading it. So if we now call set up file here, and I want you to check if set up file below zero, then return minus one all I wanted to do and we also need return zero in the set up foul function guys, because if everything went okay, we want to return zero. So currently, this should set up our file. If we can pilot now, we can see we see nothing, which means everything where I'm fine. So we're now gonna ask the user to choose some options. So let's now create another function called shoes option the returns and interest. You guys, I suggest you return zero here. That means everything went fine. And then I wanted to say if choose option below zero return minus one. Okay, if you right click and press format document, by the way, Visual CO will structure code nicely for you. So in here Now, we're now gonna ask the user to enter an option. That's all we're going to do. And there will be a few different options. We're gonna have options for adding new books and for reading books. So let's now go scan. If I and we're going to go option and we're gonna need interest you for that as well on putting absent here to get the address. So if you remember, scan F will read from the keyboard, and in this case, we're reading a number, right? So we are now going to enter a switch. So when you're a switch option and these are the options they can have, So at the top of the file, I want you to define some definitions, so go to find option curate book, and that's gonna be zero to find option. Read a book on that will be one. Now what I want you know to do is go Case option re book. And I just wanted to go print af you selected to read a book. Excellent. And now at the bottom here. I wanted to go to fault. I wanted to go print f um no invalid option chosen. I just wanted to return minus one. So if they enter an invalid option, we're gonna return minus one, which will cause is to leave the program because we check here. If the option was bad, we returned minus one and leave the programme. So just compel that. Now I'm run it into an option. So less to 50. Invalid option shows him. Now, let's zero in. Valid option chosen. Do one. You selected to read a book. So that's how that works, right? Let's now go. Case option. Great book, because that's what we really care about. Now we can come back to the reading option later. So go printer. You created a book and also put the problem you lying terminates Here is Well, guys, we now Kampala run that into an option zero you created a book. Enter option one. You selected to read a book to Invalid option Chose him. Que? Excellent! So we're now going to coal our function. We created our handle crate in the great book. So get rid of the print f hands will create on this will output a result. So at the top here want you to go insta rus equals zero. Then it here do our es equals handle crate and I say if our yes below zero return our yes So if handled, create returns an error. Let's return from here. So if we now go back to handle create, we can now ask some more options Print f and to the books name. So what I now want you to do is above this print f just go struck book beef for Buck So we correct a structure. But Colby So what I now want you to do is go a new line f gets be dark, tighter And I wanted to do size off be dark title and then here s city in So while they still do this will read from the keyboard and store a maximum of 20 breaks into our book's title on Obviously Size Off gets us the size of that title variable in this structure, which is 20 bites because it's an array. Remember, if this was a pointer size of would not work in this case because size off gives us the size of this variable, which is 20 bites because Charles one bite right, So So that should put the title they entered into our book's title on. We don't need to do a 9% here because remember, a raise automatically returned their address when you reference them. Now, if we now do print F book name percent s backlash and be dark title on this what, this will output the name they entered. So? So, if you're now compile, um, running that you'll notice a problem. Enter option 00 what's this? It doesn't wait. F gets doesn't wait. Why is that? While there's a reason for that, if we go back to our choose option scan, F only reads the intra jer on when you enter zero. It does give zero, but it also has a new line character that you can't see because as soon as you press enter , creates a new line, right? So what the F gets then does it then reads that new line and assumes that's what the user entered. So has a way around that after scan, if just you get shot on what that will do they will read the new line that they they entered by pressing the enter key. If we now compile that again, so make sure there's get sharp below scan scan F in shoes option we now run that again. Interruption zero and two books Name? I don't know. Wizard of Balls. There you go. Book name. Wizard of Oz That worked. So that puts that as expected. So we can now do. We can now ask for the description. So let's now say Prince F and to the books description. And then we now do f gets be dot description sighs off, be duck description, STD in and then we can then do print F book description percent s back session be dot description and that will that will allow him to enter the description. And it'll output that description to them. So we now compile that again. Answer up. Zero for right. Hello, Book. How are you, Brooke? and you can see that works perfectly. So, Arnie are tight book title and description and now both stored in book. So now what you can do is you can write that book to the file. So we now have to do is write the foul. So just go f right ham percent b because we're going to write the entire structure to the file and ask for an element size. Just put size off. Be an element. Count one on then for the foul per f. And while this will now do this will write our entire structure to the file because that the elements size is the size of structures will write one block of the size of our structure. Therefore, writing our entire structure right. And we can use if conditions here to check if that that right failed. But I'm not going to do this here because I want to keep it really simple for you guys. So if we now compile that now gcc main dot c, Dachau main and we run May do zero books Name. Hello? Book. How are you? Press Enter Andi. Now that's written to the file. So we go back to dated up in It says this is a binary files. You want to open it, do that and you can see that it's written off file. And if we now click on our file browser and we're gonna we're going to open it with neo. So if you right click on Dated up in On Click Edit with Hex Editor Neil on, what will happen is load and you can see Hello, book. How are you? So you can see all of this is start. But what is all this garbage by here? Well, we didn't initialize our be by setting it all to all to zero. We didn't do that. And that's why this is happening. So what we need to do, we need to set all of this memory and be 20 eso that so that we see zeros instead of random stuff here. Because this stuff here is the stuff that is on the stack at the time we create be because we don't set the entire array. There is some junk left over un initialized bites, if you will. So what we can do is if we scroll up, we need to include the string dot ph head of foul and then that would give us access to men set on. We can Then do men set and they last for destinations to just put em person be the address of B. They last for a value. The value we want to set this too. So do zero and then do size off B. So while that'll do, is that will set the entire be structure to zero to nose. And if we now close close hacks other than you, make sure you do that. Otherwise it won't last to open it again and then go Jesus, he may not see Dachau. May I wantedto run main again and it last for an option. Do zero into the books Name Happy book. How are you? And now if we go back, State is up in without hexes and neo one small right click at it with Hex Editor Neil, You can now see that it looks a lot better. All the bites we haven't initialized are set to zero because we told it to not decimal zero . It is set to binary zero. It isn't the decimal equivalent of zero guys. Remember the asking table. So all of these air now zeros, which is what we want it. So all of these bikes that aren't set are basically part of the description title that we didn't need to set because the description wasn't long enough or the title wasn't long enough. Now we've saw one buck indebted up been successfully. Congratulations. So if we now run that again, unless store second book on, we'll call it. I don't know, Um, the Godfather or whatever. Uh, this is a good book. And if we now go back, Texas is a neo again. Then we open it. You can see that it's over, written it. So why did it override it? Well, because we didn't seek to the end of our stream. So the foul pointer is planning at the start of a stream at the start of our files overwrites the old one. So what you can do to do that just before I fright do f seek and we're going to say f f for the foul stream. It's gonna ask for a lot off said just zero on. We're going to seek the end on this opposition is at the end of our file. We now, uh compile that again. I'm run that on now. Enter zero. And we're gonna enter in a high Potter. I didn't spell that. Right. Well, this is a great book. And now if we now go back and we right click to open in Hex Editor Nero again, you can now see it works is expected. We have two books here. We have the Godfather on. We have ah, Harry Potter book here, and this is all stored. Is binary guys rights? Excellent. So we've now got our creation functionality. 43. Simple Book Program Part 2: So in the last lecture, we learned how to correct box. Now let's make it so we can read those books. So what I want to do, I want to create a new definition. Call it option list bucks. I do. Too decimal, too. So if they type two, they'll have the books listed to them. So we're gonna go in that case, option this books. And now I want us to create a function for handling that. So if we go up to here handle create, we're gonna create new function, we're gonna call it handle list, Okay? And now all this is going to do, it's gonna go through the books on list them out. So I sco struck to be set struck Book B, which will hold our book, and then we want to set the file position. It's the start of the file. And then once we've done that, that'll implant to start the file. So the reason we need to do this is because if they dick parades on, we seek to the end, then we need to seek back now in this case because our program ends as soon as they've created you won't have to do this. But if our program was to continue running, then you would need to be able to set back to the beginning of the foul. So we'll just use this is good practice. So now what I want you to do is I want you to go f read and it's gonna ask for about first less passing em. Some be the dress of B. It's gonna ask elements size. So that's two size of B. And then finally, it's gonna ask the element count. So let's do one. And now we're gonna pass an F for our stream, and all I want to do now is this. Do this if f read equals one, because remember, we're reading one block, one element that is the size of our book. So they still read that. But on def, it reads it then. Then this will be executed, right? But it make more sense for this to be a while because we want to read all the books to change this to a wild and then that would go through and read every single book until there's no more books to be read. So we should be over Now go. Something like this Print f um and we should be to go s and be doc title. Prince Seth? Yes. Be that description. We should be able to do that. So if we now, uh, go back to our switch on type handle list and we're going to compile that now, Oh, main dot c guys, not CBP. And then we're gonna run that file when it's compiled. So we're gonna run. That is going to say enter an option on option list books is number two. So if we type two, it'll list the Godfather. This is a good book, Harry Potter. This is a great book, so you can see we've now read those books from there. So what? If you want the baby to select a book, then what we can do is we can have it. So each of these gets an index, and then you can enter the index to be able to view more information. But in order to do this properly, we're gonna need to use the heap. So this is a good example of when to use the heap. So what we do here, we do in future index equals zero in here to index plus plus stack to increment the index Garrett a description because we don't display all the information here. Now we do percent pie dash on here do index. So if we can Pollock now, you should be able to see if we press two zero. The Godfather one. Harry Potter, Harry Pooter. So what? We want to be a uses indexes to view more information. So how do we do that while we can use my rock? Now there's two potential ways to do this. You can allocate some memory and and re allocated on each iteration to increase the size. You can look into the reallocate function memory function if you want to learn about that as it was not taught on the memory lecture. Um, however, we will just you stand up Malek for this. So what we can do is first, we need to find out how many box there are, so let's create a function. Just call it how many books. So while this will do this way, now, need to find out how many books there are and how you can do that's easy enough. Seek to the end, right and then do total size unsigned long total size have toe. I'm passing if there seek back to the beginning. And now the how many books there as the total size divided by the size off struck book on that will give us how many books there are. Okay, so you could also have some sort of header in your actual Bynum e file on that could tell you how many there are. But this is just easy, because we can just divide by the size, right? So how many books this? This equation. He'll return that because we get the total size of the file. We divided by the size of the book on. And that's how many books there are. Right? So what we can now do? We can say in Georgia, total bucks equals how many books. And then once we know how many books there are, we know now how much data to allocate? So just to struck book, ask a risk. PTR equals struck book. Ask risk. My lock. Um, my lock size, off struck book not supplied by total books. You can also use kallakis few preferred, which will allow us to basically just to this on. That will be the size of the book on how many books there are. And then it would do the multiplication for you. But just to keep things simple, I like to use the my luck just to show you guys that this is how it's done. So the total size were allocating on the heap is the size of the book multiplied by the total books. Now, now we can do this. Men copy. Uh, PTR PTR index. I should say I'm print Empson here because we're getting the address off this index in the in the in the pointer because you can access pointers through indexes as well, right? So if this was zero, we're accessing Book one. If this was one where access and book to Onda how that works. This is you put an percent before accessing the pointer on. Then you use the index as you would, and and that's basically saying I want I want to push forward and get get this book and not not the one at the beginning. Okay, so now we do that, and then we do source. So we do em some be size off b And now that should work. Fine. Just to test, this works completely fine. Let's do for inch A I equals zero I below total books I plus plus print f I I mean, NFs There you go. Now that should work. We run that now, compile. Um, run it and we can see Harry Potter if you put one in there. Oh, yeah, the godfather and high parts. You can see its output it them correctly, which is good. That's what we wanted. So if you now move this pointer up here on just two PTR and we're gonna play top far file just right next to file on, we're gonna set this to know she zero and I wanted to do the same toe file. Pointer is well on. Then, once we've done that, it's added it'll into memory force. So now we should be able tow Ask the user again. Another question. Which books you want to read? So we'll do that now. So we go, uh, print f, choose a book, and then we go Scana sent I and here we do option. I'm sand option on. Just appear we're going to go into option equals zero so it will install that the option they chose in the option. Right? So now what we need to do, we just need to do some bounds check. And so we don't crash our program. Right? So we say if option below zero for option above, um, total books, it will be above all equals. Actually, because we started zero for the book count, then print F Invalid book Onda. We just do not lying to Germany's and then we just do the turn minus one. Okay on. Do you return zero down here? If everything went fine now, we should now finally be out of ur buck. So all you have to do is go view Buck PTR option. That's all you have to do. And if we now go up here, we can go and create that view book function. Avoid view book struck book book. And now we now should be had to do print F title sent s accession book title. Prince F oh, Prince F description percent s back session book description, if you know, compel that you can see it's complaining. That's because we need to put our m percent in. So we go back to hear view book doing an percent here because we want to get the address of this book. Paul, That main to says, Choose a book. Choose. Choose to invalid book. Try that again. Choose one. Harry Potter. This is a great book. Choose zero. The Godfather. This is a great book. Choose minus one invalid book, Steve. Now, Major program be able to create Amri bucks, which is excellent. Congratulations. So I think we said we were gonna put a flag to be able to specify whether the book had sold or not. So we're going to do that on the final part of this tutorial, Part three. 44. Simple Book Program Part 3: Welcome. So now we're going to aunt a flag, which basically says, Has this book being sold? Andi, I want to show you how to do this because we're going to use our bit wise operations. Because when I when I explained that in the bit wise lecture, I explain to you how it worked. But I never showed you a scenario where could be used, so it makes sense to do it in this project. So what I need you to do is I need you to go at the very top of the file type death on same shot book flags. So remember, type deaf allows us to define a type on given alias name. So Book Flags is is essentially an unsigned shot. Right? So in here, just to book flags, flags all you have to do well, you have to do. And now, just above book flags to define book flag sold andan that's gonna be defined. 20 b 12341234 Garrett of the final zero put a one so it's gonna be binary one, that you can also represent this like that or like that. But when I work with bit masks. This is called bit bit masking. By the way, what we're doing right now with these book flags is bit masking. That's what that that's the technical term for this. But, um, I always prefer to write it as binary, so it's very clear which flag is being set. But that's up to you. How you guys want to write that a lot of people like to do hacks a decimal. When I work with bit masks, I always use binary because I can clearly see which bit is being set. Maybe it's this bit this the That's the flag, right? You know, it's easy to see, So Okay, so once you've done that, uh, make sure, you know, semi colon there, By the way, I have a feeling one of you might have done it. Um, let's now school down Andi in our book create, because by the way, you're gonna have to delete this file and re created because we changed the structure so it won't line up correctly. But anyway, back, back, toe handle, create them. What I now want to do is I want to ask them. I want to ask these guys, uh, has the book sold? That's all I want to say. So what we're now going to do is ask them. Yes, on, though. So now we're gonna go, um, char see equals zero. And we're going to go, uh, skin if percent c and we're gonna on percent c. So it'll really everyone character that they type. So we're gonna be looking for a yes or no value. So here we can say, um, if c equals equals why or c equals equals lower case. Why, then what we want to do then is is set the book flags. So we do that by going be dot flags or equals, Um, on this a bit Wiesel, remember? And we're gonna go to the but flag sold, you know? I mean, I'm assuming you followed through all of the lectures because I'm not really explaining this because I assume that, you know, because you followed the course all the way through, right? I I'm just basically using what you've learned to help you build a project. So you can see where you would practically use thes skills. So if they enter yes than the book, the books flags is marked as sold because we bit mass that with a bit wise or so, If you've forgotten what that is, look up a bit wise or and you'll understand how this works. The binary here is Ord, with the binary in our flags bearable. Now then what I now need to do is in our view book, I need to say if buck flags and percent book flag sold. So obviously this does a bit wise and on the flags with the book flags sold operator and of a city, the results here will be above zero if their flag is set. So this is why this is true because it is non zero. So the if statement runs because our book flag sold its said if our book flag soul wasn't set, then this would obviously return zero on. Therefore, this code would not run because zero is false on false does not allow if statements to run . So we're gonna go in here now. Print f. This book was sold. Sorry. Just apologize to them or whatever. Maybe they wanted to buy the book. Andi, if we now go to our, uh, our command problems and we're going to see d into this folder to compile this and we're going to go in here. We're gonna go main, and we're gonna go GCC main dot C Dachau May, and then we're gonna run May. It's going to send you an option 20 wait a minute goes. We need to delete this file first. Otherwise, this is not going to read the data properly because I dated up being doesn't contain the flags. Variable. Right, So the data stored here won't be able to be read back correctly. So if you delete that and we're gonna create new file called David, I've been again just like that. Okay? And now we can finally come problem in the programs to compile it. Run it. I'm gonna use option zero. So he's asked me for the books name. I'm gonna say how a product, uh, this is a good book. Has the book sold? Yes. Okay, good. So if I Now, just if I now do mean again and I use option two, it says, choose a book. So I choose high Potter, and it tells me this book was sold. Sorry. You say so I run main again and I do Zero inter books. Name Godfather. Uh, great book. Now I'm going to say that it wasn't sold. And if I never in that we do to here one we don't see that this book is sold because that flag isn't set. But if we do to zero again for how you Paula, this book is sold. Sorry. So there's one more thing we needed to do which I left out until now. And that is we need to free our book pointer on. We need a free our file. Otherwise, we have a memory leak now, because our program ends As soon as we vented this in the operating system or community, clean it up. But if this code was to keep running, um, then our memory leak will present were possessed, which is not nice. So what we're gonna do, um, in our handle list? You see our pointer here after view book? We're just gonna free it. So we're going to go free PCR That's all I want you to do. And then in arming function, I wanted to do f close F which will close our file pointer. I don't do free on the file point f close handles all that internally for you, and it closes the foul correctly. Uh, okay. So back to our Melo. So, yeah, you can see we allocate the memory here, we output the book, and then we free the memory that we allocated passing it back to the operating system so it can recycle that memory. Now, we we didn't have to use my lock here, but the reason I did was because I wanted to show you a reason to use it. Um, there are many good reasons to use Matlock on the heap. Um, however, I could have got away without it in this program if I wanted to. Another alternative To do this without the Matlock memory function would be to pass the index into some sort of function that would then seek to the file. It would load up that particular element and an output that to you that's how we could have avoided using the heap entirely. However, I did want us to practice on Matlock skills again. Which is why we did this on this is a perfectly acceptable solution. So long as, uh, data Dobbin doesn't get too large because obviously here. We load absolutely everything in. Okay, well, congratulations, guys. Using everything you've learned, you built a little book program. Congratulations on using skills. You've learned. You can now take this a lot further. Ah, lot of what I've told you is used all over. See, regardless of which field you're in, you could be in kernel development, for example. Ah, lot of this same stuff is still used. Such Aziz memory allocation, the functions air named a little differently. But it's still the same concept. So what I'm trying to say is you can take what you've learned here. Now, toe any field of C programming that you like. It's the same concept all around. Eso I'm I hope that you enjoyed this video on graduations on your project.