I initially wanted to make a youtube tutorial series, but I haven’t got the setup ready and the semester has already started. So, I am starting out as a blog series. I’ll attach screenshots and code. The setup I’m using is VS code as editor and GCC as C compiler on a windows 10 machine. This setup works on linux and mac as well. More on the setup here.
Today we are going to discuss the MAIN part of a C program, aptly named the ‘main’ function.
The part of the code marked by the yellow box is called the main function. Some important characteristics that you may already know are:
- It is the entry point of the program.
- It is a function.
- Every C program must have a main function.
But just as any other field of science, in computer science too, everything is not exactly what they seem.
First of all, the compiler defines the point of entry of a program. In any standard C compiler this entry point is named ‘main‘ as a convention only. It can be changed by editing the compiler. This brings us to the conclusion that every C program doesn’t need to have a main function, rather it needs an entry point. In reality main function is the standard name only on systems that have an operating system, e.g. PCs. C programs can also be written on embedded systems which doesn’t have operating systems. We’ll discuss more about compiler and operating systems in subsequent blogs.
Lets now discuss about the ‘function‘ part in main() function. As the semester has just started, you may not have been introduced to the concept of functions in programming. In layman terms, a function is a block of code which performs a certain operation. This concept of grouping specific codes to perform some task dates back to early days of development of programming.
A basic CPU executes instructions stored in the memory(RAM) in a line by line order. The instructions stored in the memory are in binary bits (grouped in bytes represented by hexadecimal digits). In the earliest programs these hex codes(byte codes) were fed directly into the RAM by the programmer, and when execution started, the CPU executed instructions sequentially one byte after another from the RAM. So to perform a specific task multiple times, the same group of hex codes have to be written over and over. This made the programs long and since RAM in those days were very small, programmers invented a way of reusing groups of codes performing a particular task and named it a subroutine.
These subroutines were stored in different parts of the RAM, away from the main program and were referred to by the program when it needs to perform that specific task. The subroutine upon execution generated some values which were returned to the main program. The subroutine also had access to some of the values generated during the execution of the preceding codes. This is one of the most fundamental programming principle and is applicable in all modern programming languages.
Thus we can broaden our definition of functions as reusable chunks of codes, which are called by the program during execution, with or without access to some values already generated by the program, and upon completion it may return a value back to the program. I use the word ‘may‘ because some functions can perform a task that doesn’t require it to return back any value. The access to generated values can be provided by passing those values as arguments in the function description. So since main() is also a function, it is called by the program execution and the program expects it to return a value.
The compiler passes the instruction to the operating system to call the main function at the very start of program execution. In most programs no values are passed to the main function as arguments, but some programs do. At the end of execution, the operating system expects a return value, which tells the operating system whether the execution was successfully terminated or not. The value is standardized as ‘0’ in case of successful execution, and any other value in case of failure. Since this standard value is an integer, we write int main() while typing the program. This int here is called the return type of a function.
But some of you might have seen programs using void instead of int as the return type of the main function. It is valid because void returns no value, and returning no value is equivalent to returning ‘0’. Now that you have some idea as to why the main function is written the way it is, we will further discuss about functions in general in the next blog.
Lastly here are the terminal commands to compile and run the program and the output of this simple program.
I’m running gitbash CLI instead of standard command prompt so that the commands are uniform over all three major operating systems(windows, linux, mac). The code editor has an integrated terminal so I don’t have to separately open another terminal window.
In this blog I have made reference to older technology in computing. It is very important to know the history of development of programming to better understand the core concepts. I have a written a blog about this here. You’ll also have a better understanding about subroutines when you study the subject microprocessor.
If you liked this article please comment and show your support and interest so that I’ll be motivated to continue this effort. Like our facebook page if you haven’t already. And if you have any questions please comment. I’ll try to reply all.