This commit is contained in:
Miloslav Ciz 2022-04-02 00:51:11 +02:00
parent 71b1b8c0d5
commit 21b462954a

View file

@ -1,6 +1,6 @@
# C Tutorial
This is a quick [C](c.md) tutorial.
This is a relatively quick [C](c.md) tutorial.
You should probably know at least the completely basic ideas of programming before reading this (what's a [programming language](programming_language.md), [source code](source_code.md), [command line](cli.md) etc.). If you're as far as already knowing another language, this should be pretty easy to understand.
@ -73,10 +73,10 @@ written in the command line.
Now let's see what the source code means:
- `/* simple C program! */` is so called *comment*, it does nothing, it's here only for the humans that will read the source code. Such comments can be almost anywhere in the code. The comment starts at `/*` and ends with `*/`.
- `// include IO library` is another comment, but this is a line comment, it starts with `//` and ends with the end of line.
- `#include <stdio.h>` tells the compiler we want to include a library named *stdio*. This is a standard library with input output functions, we need it to be able to use the function `puts` later on. We can include more libraries if we want to. These includes are almost always at the very top of the source code.
- `int main(void)` is the start of the main program. What exactly this means will be explained later, for now just remember there has to be this function named `main` in basically every program -- inside it are commands that will be executed when the program is run. Note that the curly brackets that follow (`{` and `}`) denote the block of code that belongs to this function, so we need to write our commands between these brackets.
- `/* simple C program! */` is so called *block comment*, it does nothing, it's here only for the humans that will read the source code. Such comments can be almost anywhere in the code. The comment starts at `/*` and ends with `*/`.
- `// include IO library` is another comment, but this is a *line comment*, it starts with `//` and ends with the end of line.
- `#include <stdio.h>` tells the compiler we want to include a library named *stdio* (the weird [syntax](syntax.md) will be explained in the future). This is a standard library with input output functions, we need it to be able to use the function `puts` later on. We can include more libraries if we want to. These includes are almost always at the very top of the source code.
- `int main(void)` is the start of the main program. What exactly this means will be explained later, for now just remember there has to be this function named `main` in basically every program -- inside it there are commands that will be executed when the program is run. Note that the curly brackets that follow (`{` and `}`) denote the block of code that belongs to this function, so we need to write our commands between these brackets.
- `puts("It works.");` is a "command" for printing text strings to the command line (it's a command from the `stdio` library included above). Why exactly this is written like this will be explained later, but for now notice the following. The command starts with its name (`puts`, for *put string*), then there are left and right brackets (`(` and `)`) between which there are arguments to the command, in our case there is one, the text string `"It works."`. Text strings have to be put between quotes (`"`), otherwise the compiler would think the words are other commands (the quotes are not part of the string itself, they won't be printed out). The command is terminated by `;` -- all "normal" commands in C have to end with a semicolon.
- `return 0;` is another "command", it basically tells the operating system that everything was terminated successfully (`0` is a code for success). This command is an exception in that it doesn't have to have brackets (`(` and `)`). This doesn't have to bother us too much now, let's just remember this will always be the last command in our program.
@ -104,7 +104,7 @@ Programming is a lot like mathematics, we compute equations and transform numeri
We can create variables named `x`, `y`, `myVariable` or `score` and then store specific values (for now let's only consider numbers) into them. We can read from and write to these variables at any time. These variables physically reside in [RAM](ram.md), but we don't really care where exactly (at which address) they are located -- this is e.g. similar to houses, in common talk we normally say things like *John's house* or *the pet store* instead of *house with address 3225*.
Variable names can't start with a digit. By convention they also shouldn't be all uppercase or start with uppercase (these are normally used for other things). Normally we name variables like this: `myVariable` or `my_variable` (pick one style, don't mix them).
Variable names can't start with a digit (and they can't be any of the [keywords](keyword.md) reserved by C). By convention they also shouldn't be all uppercase or start with uppercase (these are normally used for other things). Normally we name variables like this: `myVariable` or `my_variable` (pick one style, don't mix them).
In C as in other languages each variable has a certain **[data type](data_type.md)**; that is each variable has associated an information of what kind of data is stored in it. This can be e.g. a *whole number*, *fraction*, a *text character*, *text string* etc. Data types are a more complex topic that will be discussed later, for now we'll start with the most basic one, the **integer type**, in C called `int`. An `int` variable can store whole numbers in the range of at least -32768 to 32767 (but usually much more).
@ -128,7 +128,7 @@ int main(void)
```
- `int myVariable;` is so called **variable declaration**, it tells the compiler we are creating a new variable with the name `myVariable` and data type `int`. Variables can be created almost anywhere in the code (even outside the `main` function) but that's a topic for later.
- `myVariable = 5;` is so called **variable assignment**, it stores a value 5 into variable named `myVariable`. IMPORTANT NOTE: the `=` does NOT signify mathematical equality but an assignment (equality in C is written as `==`); when compiler encounters `=`, it simply takes the value on the right of it and writes it to the variable on the left side of it. Sometimes people confuse assignment with an equation that the compiler solves -- this is NOT the case, assignment is much more simple, it simply writes a value into variable.
- `myVariable = 5;` is so called **variable assignment**, it stores a value 5 into variable named `myVariable`. IMPORTANT NOTE: the `=` does NOT signify mathematical equality but an assignment (equality in C is written as `==`); when compiler encounters `=`, it simply takes the value on the right of it and writes it to the variable on the left side of it. Sometimes people confuse assignment with an equation that the compiler solves -- this is NOT the case, assignment is much more simple, it simply writes a value into variable. So `x = x + 1;` is a valid command even though mathematically it would be an equation without a solution.
- `printf("%d\n",myVariable);` prints out the value currently stored in `myVariable`. Don't get scared by this complicated command, it will be explained later. For now only know this prints the variable content.
- `myVariable = 8;` assigns a new value to `myVariable`, overwriting the old.
- `printf("%d\n",myVariable);` again prints the value in `myVariable`.
@ -159,6 +159,115 @@ calculates and prints your BMI (body mass index).
## Branches and Loops
When creating [algorithms](algorithm.md), it's not enough to just write linear sequences of commands. Two things (called [control structures](control_structure.md)) are very important to have in addition:
- **[branches](branch.md)**: Conditionally executing or skipping certain commands (e.g. if a user enters password we want to either log him in if the password was correct or write error if the password was incorrect). This is informally known as **"if-then-else"**.
- **[loops](loop.md)** (also called **iteration**): Repeating certain commands given number of times or as long as some condition holds (e.g. when searching a text we repeatedly compare words one by one to the searched word until a match is found or end of text is reached).
Let's start with **branches**. In C the command for a branch is `if`. E.g.:
```
if (x > 10)
puts("X is greater than 10.");
```
The [syntax](syntax.md) is given, we start with `if`, then brackets (`(` and `)`) follow inside which there is a condition, then a command or a block of multiple commands (inside `{` and `}`) follow. If the condition in brackets hold, the command (or block of commands) gets executed, otherwise it is skipped.
Optionally there may be an *else* branch which is gets executed only if the condition does NOT hold. It is denoted with the `else` keyword which is again followed by a command or a block of multiple commands. Branching may also be nested, i.e. branches may be inside other branches. For example:
```
if (x > 10)
puts("X is greater than 10.");
else
{
puts("X is not greater than 10.");
if (x < 5)
puts("And it is also smaller than 5.");
}
```
So if `x` is equal e.g. 3, the output will be:
```
X is not greater than 10.
And it is also smaller than 5.
```
A note on **conditions** in C: a condition is just an expression (variables along with arithmetic operators). The expression is evaluated (computed) and the number that is obtained is interpreted as *true* or *false* like this: in C 0 means false and anything non-0 means true. Even comparison operators like `<` and `>` are technically arithmetic, they compare numbers and yield either 1 or 0.
Next we have **loops**. There are multiple kinds of loops even though in theory it is enough to only have one kind of loop (there are multiple types out of convenience). The loops in C are:
- **while**: Loop with condition at the beginning.
- **do while**: Loop with condition at the end, not used so often so we'll ignore this one.
- **for**: Loop executed a fixed number of times. This is a very common case, that's why there is a special loop for it.
The **while** loop is used when we want to repeat something without knowing in advance how many times we'll repeat it (e.g. searching a word in text). It starts with the `while` keyword, is followed by brackets with a condition inside (same as with branches) and finally a command or a block of commands to be looped. For instance:
```
while (x > y) // as long as x is greater than y
{
printf("%d %d\n",x,y); // prints x and y
x = x - 1; // decrease x by 1
y = y * 2; // double y
}
puts("The loop ended.");
```
If `x` and `y` were to be equal 100 and 20 (respectively) before the loop is encountered, the output would be:
```
100 20
99 40
98 60
97 80
The loop ended.
```
The **for** loop is executed a fixed number of time, i.e. we use it when we know in advance how many time we want to repeat our commands. The [syntax](syntax.md) is a bit more complicated: it starts with the keywords `for`, then brackets (`(` and `)`) follow and then the command or a block of commands to be looped. The inside of the brackets consists of an initialization, condition and action separated by semicolon (`;`) -- don't worry, it is enough to just remember the structure. A for loop may look like this:
```
puts("Counting until 5...");
for (int i = 0; i < 5; ++i)
printf("%d\n",i); // prints i
```
`int i = 0` creates a new temporary variable named `i` (name normally used by convention) which is used as a **counter**, i.e. this variable starts at 0 and increases with each iteration (cycle), and it can be used inside the loop body (the repeated commands). `i < 5` says the loop continues to repeat as long as `i` is smaller than 5 and `++i` says that `i` is to be increased by 1 after each iteration (`++i` is basically just a shorthand for `i = i + 1`). The above code outputs:
```
Counting until 5...
0
1
2
3
4
```
IMPORTANT NOTE: in programming we **count from 0**, not from 1 (this is convenient e.g. in regards to [pointers](pointer.md)). So if we count to 5, we get 0, 1, 2, 3, 4. This is why `i` starts with value 0 and the end condition is `i < 10` (not `i <= 10`).
Generally if we want to repeat the `for` loop *N* times, the format is `for` loop is for `(int i = 0; i < N; ++i)`.
Any loop can be exited at any time with a special command called `break`. This is often used with so called infinite loop, a *while* loop that has `1` as a condition; recall that 1 means true, i.e. the loop condition always holds and the loop never ends. `break` allows us to place conditions in the middle of the loop and into multiple places. E.g.:
```
while (1) // infinite loop
{
x = x - 1;
if (x == 0)
break; // this exits the loop!
y = y / x;
}
```
The code above places a condition in the middle of an infinite loop to prevent division by zero in `y = y / x`.
Again, loops can be nested (we may have loops inside loops) and also loops can contain branches and vice versa.
## Simple Game: Guess a Number
With what we've learned so far we can already make a simple [game](game.md): guess a number. The computer thinks a random number in range 0 to 9 and the user has to guess it. The source code is following.