Now we’d like to show you a very simple (and completely useless) program written in the “C” language. Using this example, we’ll show you some basic rules as we modify the program many times, enriching it with various elements and simultaneously expanding our programming knowledge.
First, we define our expectations for the program. They’ll be very modest. We want a short and rather meaningless text to appear on the screen. Let's assume that the text should proclaim to the world:
It's me, your first program.
We don't expect anything more from it so far.
What further steps should our first program perform? Let's try to enumerate them here:
- to start;
- to write the text on the screen;
- to stop
This sort of structured and semi-formal description of each step of the program is called an algorithm. The sources of this word can be traced back to the Arabic language, and it originated in early medieval times, which may be the pretext to note that the beginnings of computer programming lie in very ancient times.
Now it's time to see our program.
It looks a bit mysterious, doesn't it? Now we’ll look carefully at each line of the program, explaining its meaning and purpose. The description is not particularly accurate and those who know the “C” language would probably already conclude that it’s too simplistic and somewhat childish. We did this on purpose – it’s not our intention to build Rome in a day.
Let's start.
Pay attention to the character #
(hash) at the beginning of the first line. It means that the content of this line is a preprocessor directive. We’re going to tell you more about the preprocessor a little bit later, but for now we’ll just say that it’s a separate part of the compiler, whose task is to pre-read the text of the program and make some modifications to it. The prefix “pre” suggests that these operations are performed before the full processing (compilation) takes place.
The changes the preprocessor introduces are controlled entirely by its directives. In the example program, we’re dealing with the include directive. When the preprocessor encounters that directive, it replaces the directive with the content of the file whose name is listed in the directive (in our case, this is the file stdio.h
). Note – the changes made by the preprocessor never modify the content of your source file in any way. Any alterations are made on a volatile copy of your program, which disappears immediately after the compiler finishes its work.
You may ask why we want the preprocessor to include the content of a completely unknown file stdio.h
. Writing a program is similar to constructing a building with ready-made blocks. In our program, we’re going to use such a block and we’ll use it when we want to write something on the screen. That block is called puts (you can find it inside our code), but the compiler knows nothing about it so far. In particular, the compiler has no idea that puts is a valid name for that block while puts isn't. The compiler needs to be aware of this. This preliminary information needed by the compiler is included in the files whose names usually end with “.h” (header). These files are commonly called header files.
The stdio.h file (defined by the standard of the “C” language) contains a collection of preliminary information about ready-made blocks which can be used by a program to write text on the screen or to read letters from the keyboard. So when our program is going to write something, it’ll obviously use a block called puts, which is able to do the trick. We don't want the compiler to be surprised, so we must warn it about that. The compiler's developers put a set of such anticipatory information in the stdio.h file. We only have to use the file. This is exactly what we expect from the include
directive.
You might also ask where the stdio.h
file is located. The answer is simple but not as accurate as you may want – but that’s not our problem right now. The preprocessor knows where it is. We’ll return to the issue when we begin the detailed story of preprocessing.
We’ve already mentioned something about blocks. Let's go a little deeper now. One of the most common types of blocks used to build “C” programs is functions. If you understand functions only in a purely mathematical sense, this still is a pretty good clue. Imagine a function as a black box, where you can insert something into it (not always necessary) and take something new out of it as if out of a magic hat. Things that are put in the box are called function rguments (or function parameters). Things that are taken out of the box are called function results. In addition, a function can do something else on the side. If this sounds rather vague, don't worry, we’ll be talking about functions many times in more detail.
Let’s return to our program. The standard of the “C” language assumes that, among the many different blocks which may be put into a program, one specific block must always be present, otherwise the program won't be correct. This block is always a function of the same name: main
.
Every function in “C” begins with the following set of information:
- what is the result of the function?
- what is the name of the function?
- how many parameters does the function have and what are their names?
Take a look at our program and try to read it properly, accepting the fact that you might not fully understand everything yet.
- the result of the function is an integer value (we read it from the word
int
which is short for integer) - the name of the function is
main
(we know why already) - the function doesn't require any parameters (which we read from the word
void
)
A set of information like this is sometimes called a prototype, and it’s like a label affixed to a function, announcing how we can use that function in your program. The prototype says nothing about what the function is intended for. It’s written inside the function and the interior of the function is called the function body. The function body begins where the first opening bracket {
is placed and ends where the corresponding closing bracket }
is placed. It might sound surprising, but the function body can be empty – this just means that the function does nothing.
We can even imagine a function that is lazy – it would be encoded like this:
void lazy(void) { }
This drone provides no result (the first void
), its name is “lazy”, it doesn't take any parameters (the second void
) and it does absolutely nothing (the blank space between the brackets).
By the way, the names of the functions are subject to fairly rigid constraints. We’ll discuss this later.
Inside the main function body we should write what our function (and thus the program) is supposed to do. We look inside and find a reference to a block called puts. This is what we call a function invocation. Now let’s consider a few important details.
Firstly, note the emicolon at the end of the line. Each instruction (precisely: each statement) in “C” must end with a semicolon – without it the program will be incorrect. A statement like this says: instruct the function named puts to show text on the screen. You might ask – how do we know that the puts function will do that for us? Well, we know it from the “C” language standards, but also, the name of the function is an abbreviation of “PUT String”. The text intended to be shown on the screen is passed to the function as a function parameter. Remember that the name of the invoked function must always be followed by a pair of parentheses (
and )
, even when the function doesn’t expect any parameters from us.
Secondly, the parameter of the function puts is text (string). For simplicity, we can assume that strings in a program in “C” are always enclosed in quotes – in that way the compiler distinguishes the text that is sent to the user of the program and the text intended to be compiled (translated into machine language). This distinction is very important. Take a look:
int main(void);
The line above is the main function prototype.
We’re coming to the end now. There’s only one line left to explain in our program. This is:
return 0;
Besides the function invocation, this is another statement of the “C” language. Its name is just return and that’s exactly what it does. Used in the function, it causes the end of the function execution. If you perform return
somewhere inside a function, this function immediately interrupts its execution. The zero that you see after the word return is the result of your function main
. This is important – this is how your program tells the operating system the following message: I did what I had to do, nothing stopped me and everything is OK. If you were to write:
return 1;
it would mean that something had gone wrong, it didn’t allow your program to be successful and the operating system could then use that information to react in the most appropriate way.
Is that all? Yes! Let's look again at our program and see what’s happening step by step:
- we introduce the function
main
into our program – it’ll be executed when you start the program; - we invoke the function
puts
inside the main function – it’ll print the text on the screen; - the program finishes immediately after printing, indicating that everything you expected to achieve has been achieved.
We hope that wasn’t as difficult as it seemed at first glance. Now we’ll try to persuade the computer to compute something for us. In fact, this is what we use computers for.
0 Comments
Tell us your queries or more topics which you want