In the previous section we covered setting up our enviroment to easily compile our programs. We also created a basic hello world program to test and make sure our compiler was working. Now we will break down the Hello World program and look at what each part is doing. Believe it or not just studying this small bit of code will teach us quite a bit about how programs work in C.
hello world c
C lecture Hello Wolrd tutorial

Breaking Everything Down

Pre-Processor Directives

So, this is sort of a term that sounds really scary but it's not in any way shape or form. Most of what this is can be implied simply by the name, it's a direction given to the compiler before processing begins, a "Pre-Processing Directive" if you will. There are two main Pre-processor direcives, firstly, #include, and secondly #define. Obviously you can tell these by the # symbol. There of course are more but these are the main two you will see. We'll be talking about #include though. You'll notice the first line of our program was: 

#include <stdio.h;>
                         

    This; line of code is one of the most important ones in a program. It says "Include the following file". Now I should breifly talk about how libraries work. So in C (and C++), we have something called a header file. All a header file is, is a file that holds code that is used by a library (we will eventually make our own header files). These header files are used in conjunction with dll's and .lib files to give you the power to used pre-written code (note I kept that explanation pretty general and non specific, it's a little more detailed than that but not much more, but we haven't covered enough in programming to fully understand it yet, don't worry, this will make a lot more sense later.) So, the header file we included "stdio", is a header file which contains some basic code for using input and output. If you come from C#, this is equivalent to a using directive, or an import in Java (I believe that's what it is in Java anyway) but in C it is a little more involved once we start getting into importing other libraries (if we ever cover something that would use it, an example would be if we ever did game development we would need to know how to import libraries). Now, if you didn't really follow that (totally fair), just think of it simply as we want to use some pre-written code, and header files are our way of telling the C compiler which bits of code we need to use in order for our program to work properly.

    Alright;, so that's the first line, it just instructs the compiler to include the basic input and output libraries. At this point you may have a very legitimate question: "How on earth does the compiler know where to find the libraries?". That is an excellent question (if you didn't ask it...uhh....good effort!), open your command prompt and navigate to the Microsoft Visual Studio 12.0 folder. Go to the VC folder and type dir, you should see several files. One of these files is called "include", and like I said you should see a couple others, the other ones we care about are the bin folder and the lib folder. So earlier we talked about lib, header, and dll files. All of these files have dependencies on eachother, so you can't just include a header file in general because it doesn't hold all of the code you need, and likewise you can't just use a .lib file because some of the code is held within the dll and header file. Now when you write your own header files, they very well can contain all of the code you need but in general that's not how developers do it when they ship libraries. So if you look in the bin folder it contains dll's, the lib folder holds .lib files, and include holds .h files. This is the basic format for any library you use, so you should try to remember it if you can. When a vendor ships a compiler, they can safely assume you will use certain files, stdio being one of them, so the compiler is set up to know where to find these libraries by default, so when you include stdio.h, it just knows where that is and it plugs it in for you. This is not the case when you include other files, you'll notice in our bat file for example I've included references to GDI and User32.lib, because the C compiler does not include these by default. Again, when we get into more complex programs with other libraries we'll look at how to add references to our own libraries. Now that was an extremely long winded explanation of just one line of code and you're probably feeling extremely overwhelmed (assuming you're a beginner), but it is massively important and now that you (hopefully) understand it, you will have a very good idea of how the compiler works. Keep in mind it was a lot of explanation but you now understand the underlying way that the compiler works with external libraries and how pre-processor directives work so you actually learned a ton of stuff just from that one line of code.

Printf ()

Okay, so I'm going to skip over the line "int main()" for now. So let's talk about the line that reads:


printf("Hello World!");
                          


    So; "printf", what does that mean? Well, it's short for "Print Formatted String". You may not know what a string is yet, so another way of saying it is "Print Formatted Text". This is what we call a "function". A function is simply a small piece of code that is pre-written and does some stuff, so in this case printf is a function that outputs some text to the console window. Pretty simple right? Alright, so when we actually compile this program the compiler goes through a couple of stages to get it from a plain text file to an actual executable, one step is a step called "lexical analysis". So what is that? Well essentially one component of the compiler is a small program called a lexer, the lexer is responsible for going through the source code and essentially looking for tokens. A token can be thought of as a keyword that the compiler looks for, like the # symbol, main, and others. In this instance, if the lexer sees a set of double quotes around text, it treats this as a string, or a set of characters. One other thing you'll notice is that we put a semicolon at the end of some of the lines. This is a way of telling the C compiler to treat everything behind the semi-color as a single statement. For now this is not going to make a lot of sense, in the meantime think of it sort of like how we end sentences with periods to identify we have completed a thought or phrase. More on this later. 

Functions, the Basis of All Programming

Now I debated whether or not I should cover functions this early on, but I've decided I may as well. I'll cover them later as well, that way if it doesn't make sense now you'll get an explanation later, but if you do understand them early on it will make a huge difference in how you look at code. So I'm going to first address functions to people who come from an object-oriented language like C# or Java. So in C, a function is basically a "method" in C# or Java, infact functions and methods are the exact same thing. Why two different terms then? The reason for this is because prior to C++ everything was just a function, when C++ came along and OOP became big, you still had C underneath C++, so you had to be able to differentiate between a classes functions and a function outside of a class, so functions within a class became "Methods" and functions outside of a class were just functions. The reason you don't hear the term function used in high level OOP languages is because everything usually inherits from some sort of base class at some level, ergo everything is a method, there is no "function" because since everything is in a class in one way or another you don't need to differentiate between the two. Okay, now back to the beginners.

    Alright;, on to functions. Functions as stated earlier as merely sections of code that do certain tasks. When we use a function, we say we are "calling" the function. The basics of a function are actually quite simple, and can be illustrated like this:


Function Return Type | Function Name(Function arguments)

                          


    So; let's break each of these components down. Sometimes a function returns data back to you, this is what the "return type" is, it tells you what kind of data the function will be passing back to you. Don't worry about that part for now, we won't need to focus on it until we write our own functions because to call a function you don't really need to know it's return type. The main thing to focus on is the name and arguments. In the example of printf, printf is the name, and the argument(s) is the text we passed in. To use a function we only have to type the name and pass the arguments, we don't ever have to type the function return type unless we are creating the function because the compiler needs to know it in that case. So that sounds confusing, but I promise you it will make more sense as we go on. Think of it like those compiler switches we talked about in part 2. We can specify we want a program to do certain things depending on the switches we turn on or off, the same is true for a function (to some extent).

    Hopefully; that makes some sense, I PROMISE it will make more sense as we go on, it's generally not something you cover early on so it will be a little confusing for now. Okay, so now that we understand that (somewhat) let's cover getchar(). 

getchar()

Alright, take a breather, this next part is easy. Now that we understand functions, we can more easily talk about these commands we are using. So getchar is a function that simply waits for the user to press a key. Once the user presses the key, the program moves to the next line of code, which lo and behold is another getchar. This means that the program will wait for you to press a key twice before it moves on. Told you that would be simple. 

int main()

Another perk of talking about functions early on is this should now make complete sense even if you only understood a little bit of what I said. So first, take note of the name of our source file (the file that holds our source code). It's named "main.cpp", that's because in programming the term "main" refers to the entry point of your program. Now, everything in C at some level is a function (with a few minor exceptions), so everything for the most part needs to be in a function. This of course leaves us with the question of which function do we start with when the program runs? Well...the "main" function, that's right, main itself is a function, but you'll notice there is a difference between the main function and the printf or getchar function. The difference is main has a return type, "int". We're going to cover data types in the next lesson, but for now know that int is a way of representing a number. So what's that mean? Well, go down to the line that reads "return 0;". This tells the program to return back to the main function the value "0" once it has finished executing, and since the return value of the function is "int", it will work properly. If for example we wrote " return "Hello" ", the program wouldn't compile, because we are trying to return a string to a function that is expecting to have an int returned back to it. I remember when I was first starting out this was incredibly hard for me to wrap my mind around so I will do my best to cover it well here. Let's say we have a scenario where we want to see if our program ran properly, we have a few ways of doing this but the main way is the return value. We could in theory say "if the main function returns back the value 0, we know that it ran sucessfully, if it returns back something else, we could assume that it failed.", this sounds confusing, but it will make more sense as you write your own functions. You'll notice that there are two curly braces, an opening brace and a closing brace surrounding all of the code inside of the main function. This is because the compiler needs to somehow know what code belongs to which functions, so if we were to write our own function within the main function, let's call it "int DoStuff()", we would need to put curly braces around the code inside this function to identify it belongs to the DoStuff function, and not the main function. This all has to do with "Scope", a concept that I will cover later on, it also relates to the stack, which will also get covered probably along with scope. 
Conclusion
Alright, so that was a LOT of content just to cover hello world. I know I keep saying this but trust me when I say you learned most of the most important topics in C just now, and life should be a bit easier from here on out...at least for a while. Also believe me when I say if you are a beginner, or even a programmer who's just never worked low level before, you have no idea how much stuff you just covered, you basically learned the equivellant of what you'd be lucky to learn in 1 or 2 weeks of course work in college (at least at my college). In the next lesson, we will be covering data types, it may get a little advanced because I like to talk about how stuff works on the actual processor but to actually start using data types is pretty easy so take a breather, go get some coffee or whatever, and relax and come back ready to learn about data types!

Lesson 2: Setting up the Enviroment : Lesson 4: Data Types and Variables

Post a Comment

Previous Post Next Post