learn C with me - week 1 - main function and output operations
If you are reading this, I assume that you succesfully installed text editor of choice and C compiler like GCC or Clang. To get started create a new file with .c extension and any name you want. Good idea is to keep name short and mnemonic to make it easier to operate on it. In my case this command is doing the job:
touch hello.c
This file is a new canvas for your code. If you would like to compile it right now, then generated program will do completely nothing, because there is no code inside to execute. Let’s change it.
main function
Unlike interpreted languages like Python or JavaScript where code is being read line by line from top to down, in C you need a clear starting point in form of main function. Function itself is enough to cover whole seperate post, but for now I hope it will be enough if I say that function is reusable piece of code with its own name. To create main function simply type:
int main(void)
{
}
Now let’s break it down;
int
means that main function is returning integer after it executes. While it’s not enforced by C anymore, it’s good practice to add return value for main function.
int main(void)
{
return 0;
}
return value here is 0, because when you run your program, operating system is looking for the main function to start processing code and waits for return value with error code. It’s like operating system asking question ‘is something wrong with this code?’ and 0 (false) means there is nothing wrong and operating system can free all memory occupied by the program. Any other value but 0 means true and gives the operating system opportunity to scream and shout error messages to us.
Next there is main(void)
where main()
is reserved name for the main function and can’t be used to name any other function, while void
means that the main function is not accepting any arguments when it’s called. (the main function is called everytime you launch your program). When you will be reading code written by other people, there is great chance that instead of void
there will be int argc, const char * argv[]
which can be roughly translated to ‘function main accepts 2 argument, where the first one is integer argc number and the second one is constant array of characters called argv’. While it may sound daunting now, it becomes very handy when it comes to creating all kinds of CLI tools. argc is the number representing amount of arguments passed along with program to the shell, while argv is storing these arguments in text form, for further processing.
Then, we have pair of curly braces (this -> {}). They are holding tightly block of code belonging to the parent element (main function in this case). You may not like them, but they are making compiler’s life easier by acting as explicit start and end of the code block. They are making your life easier too, because thanks to them you know exactly which code belongs to given statement or function. Think of curly braces as twins, because they don’t really like to be alone. They need eachother to work properly.
The good news is that they don’t complain about their position, so you can position them however you want. Just be consistent, to make code more readable.
This works:
int main(void)
{
// your code here
return 0;
}
This works as well:
int main(void){
//your code here
return 0;
}
This works too, but just because you can doesn’t mean you should.
int main(void) { return 0; }
Please, don’t.
output operations
The most natural way for humans to communicate is by using their voice. While the computer can’t speak (of course it can, we just haven’t covered the audio api yet), it can display nice things. There are actually many ways of outputting text to a terminal in C, but in order to not overcomplicate things, I’ll only explain in depth the one we’ll be using most often in the near future; the printf function. The name printf stands for print formatted, which I think is pretty straightforward. It allows us to send formatted strings to standard output which is usually the terminal window where you ran your program. In order to execute any function in C, we have to call it by typing name of the function and pass to it all required arguments. It’s easier than it sounds and for printf function looks like this:
printf("hello");
In example above:
printf
is the name of the function
"hello"
is argument passed to this function
Note: “hello” is a string. It means that it’s a sequence of individual characters. In some programming languages strings are distinct data type, but in C it’s just an array of characters.
Now let’s try to put it all together
int main(void)
{
printf("hello");
return 0;
}
And let’s compile it! uh oh something is wrong
main.c:3:2: error: call to undeclared library function 'printf' with type 'int (const char *, ...)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
printf("hello");
^
main.c:3:2: note: include the header <stdio.h> or explicitly provide a declaration for 'printf'
1 error generated.
We got error from the compiler. It says that we called undeclared function. As you may see, the compiler already gave us solution to this problem which can be either including proper header file, or declaring printf function on our own, but I think that before we solve our problem it would be worth to take a closer look at it and understand why it happened.
printf function is part of C’s standard library, which is set of functions designed for performing operations like memory management, input/output operations or string manipulation and conversion so you don’t have to implement them on your own, making your C code portable, because you don’t have to write manually functions for tasks like printing text to a terminal window for every operating system. The trick is these functions are defined in files provided by a compiler and you have to ‘link’ them to your code, to make ironically- a compiler know that you are using these functions from these files, because it’s not psychic and doesn’t know that you want to use printf function from standard library, or have some super secret C library with its own cooler version of printf. That being said, let’s add printf function to our program.
#include <stdio.h>
This line is bit different from previous code, because it starts with hash symbol (this -> #). This is a preprocessor statement. Preprocessor statements are not directly part of your program, but you can think of them as useful sticky notes left for the compiler so it can do its job more efficiently (or sometimes doing it job at all) by knowing more details about code it’s working with. This statement literally says ‘include stdio.h’ which is header file where the printf command is defined. Header files are the files containing all function declarations for given library and by including them to your code, you are able to call functions from external libraries. I like to think of them as maps for the compiler so it knows that given function exists, even if is not there physically.
But lets’s get back to our code:
#include <stdio.h>
int main(void)
{
printf("hello");
return 0;
}
You can now try to compile it and it should compile without any issues. After launching it, you should see this in your terminal window:
helloProgram ended with exit code: 0
It works, but it’s still not perfect. Depending on your shell the ‘hello’ text will either display along with ‘%’ symbol, it will be displayed along with exit code, or even get into the same line as your command prompt. To get rid of this issue we need to add new line character at the end of the string. New line character is one of few escape sequences. They are meant to make it easier to represent whitespace characters and characters like ‘”’, ‘%’ or ‘*’ in code without breaking it. You can find complete list of escape sequences here. For now we will be using ‘\n’ escape sequence standing for ‘new line’ which is pretty much the same as pressing return key on your keyboard or writing <br> on your html page.