less_retarded_wiki/c_tutorial.md
Miloslav Ciz 71b1b8c0d5 Update
2022-04-01 22:37:58 +02:00

238 lines
14 KiB
Markdown

# C Tutorial
This is a 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.
## About C and Programming
[C](c.md) is
- A **[programming language](programming_language.md)**, i.e. a language that lets you express [algorithms](algorithm.md).
- [Compiled](compiled.md) language (as opposed to [interpreted](interpreted.md)), i.e. you have to compile the code you write (with [compiler](compiler.md)) in order to obtain a [native](native.md) executable program (a binary file that you can run directly).
- Extremely **fast and efficient**.
- Very **widely supported and portable** to almost anything.
- **[Low level](low_level.md)**, i.e. there is relatively little [abstraction](abstraction.md) and not many comfortable built-in functionality such as [garbage collection](garbage_collection.md), you have to write many things yourself, you will deal with [pointers](pointer.md), [endianness](endianness.md) etc.
- Considered **hard**, but in certain ways it's simple, it lacks [bloat](bloat.md) and [bullshit](bullshit.md) of "[modern](modern.md)" languages which is an essential thing. It will take long to learn but it's the most basic thing you should know if you want to create good software. You won't regret.
- **Not holding your hand**, i.e. you may very easily "shoot yourself in your foot" and crash your program. This is the price for the language's power.
- Very old, well established and tested by time.
- Recommended by us for serious programs.
Programming in C works like this:
1. You write a C source code into a file.
2. You compile the file with a C [compiler](compiler.md) such as [gcc](gcc.md) (which is just a program that turns source code into a runnable program). This gives you the executable program.
3. You run the program, test it, see how it works and potentially get back to modifying the source code (step 1).
So, for writing the source code you'll need a [text editor](text_editor.md); any [plain text](plain_text.md) editor will do but you should use some that can highlight C [syntax](syntax.md) -- this helps very much when programming and is practically a necessity. Ideal editor is [vim](vim.md) but it's a bit difficult to learn so you can use something as simple as [Gedit](gedit.md) or [Geany](geany.md). We do NOT recommend using huge programming [IDEs](ide.md) such as "VS Code" and whatnot. You definitely can NOT use an advanced document editor that can format text such as [LibreOffice](libreoffice.md) or that [shit](shit.md) from Micro$oft, this won't work because it's not plain text.
Next you'll need a C [compiler](compiler.md), the program that will turn your source code into a runnable program. We'll use the most commonly used one called [gcc](gcc.md) (you can try different ones such as [clang](clang.md) or [tcc](tcc.md) if you want). If you're on a [Unix](unix.md)-like system such as [GNU](gnu.md)/[Linux](linux.md) (which you probably should), gcc is probably already installed. Open up a terminal and write `gcc` to see if it's installed -- if not, then install it (e.g. with `sudo apt install build-essential` if you're on a Debian-based system).
If you're extremely lazy, there are online web C compilers that work in a web browser (find them with a search engine). You can use these for quick experiments but note there are some limitations (e.g. not being able to work with files), and you should definitely know how to compile programs yourself.
Last thing: there are multiple standards of C. Here we will be covering [C99](c99.md), but this likely doesn't have to bother you at this point.
## First Program
Let's quickly try to compile a tiny program to test everything and see how everything works in practice.
Open your text editor and paste this code:
```
/* simple C program! */
#include <stdio.h> // include IO library
int main(void)
{
puts("It works.");
return 0;
}
```
Save this file and name it `program.c`. Then open a terminal emulator (or an equivalent command line interface), locate yourself into the directory where you saved the file (e.g. `cd somedirectory`) and compile the program with the following command:
```
gcc -o program program.c
```
The program should compile and the executable `program` should appear in the directory. You can run it with
```
./program
```
And you should see
```
It works.
```
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.
- `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.
Also notice how the source code is formatted, e.g. the indentation of code withing the `{` and `}` brackets. White characters (spaces, new lines, tabs) are ignored by the compiler so we can theoretically write our program on a single line, but that would be unreadable. We use indentation, spaces and empty lines to format the code to be well readable.
To sum up let's see a general structure of a typical C program. You can just copy paste this for any new program and then just start writing commands in the `main` function.
```
#include <stdio.h> // include the I/O library
// more libraries can be included here
int main(void)
{
// write commands here
return 0; // always the last command
}
```
## TO BE CONTINUED
## Variables, Arithmetic, Data Types
Programming is a lot like mathematics, we compute equations and transform numerical values into other values. You probably know in mathematics we use *variables* such as *x* or *y* to denote numerical values that can change (hence variables). In programming we also use variables -- here **[variable](variable.md) is a place in memory which has a name**.
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).
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).
Let's see an example.
```
#include <stdio.h>
int main(void)
{
int myVariable;
myVariable = 5;
printf("%d\n",myVariable);
myVariable = 8;
printf("%d\n",myVariable);
}
```
- `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.
- `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`.
After compiling and running of the program you should see:
```
5
8
```
Last thing to learn is **arithmetic operators**. They're just normal math operators such as +, - and /. You can use these along with brackets (`(` and `)`) to create **[expressions](expression.md)**. Expressions can contain variables and can themselves be used in many places where variables can be used (but not everywhere, e.g. on the left side of variable assignment, that would make no sense). E.g.:
```
#include <stdio.h>
int main(void)
{
int heightCm = 175;
int weightKg = 75;
int bmi = (weightKg * 10000) / (heightCm * heightCm);
printf("%d\n",bmi);
}
```
calculates and prints your BMI (body mass index).
## Branches and Loops
## 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.
```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
srand(clock()); // random seed
while (1) // infinite loop
{
int randomNumber = rand() % 10;
puts("I think a number. What is it?");
int guess;
scanf("%d",&guess); // read the guess
getchar();
if (guess == randomNumber)
puts("You guessed it!");
else
printf("Wrong. The number was %d.\n",randomNumber);
puts("Play on? [y/n]");
char answer;
scanf("%c",&answer); // read the answer
if (answer == 'n')
break;
}
puts("Bye.");
return 0; // return success, always here
}
```
- `#include <stdlib.h>`, `#include <time.h>`: we're including additional libraries because we need some specific functions from them (`rand`, `srand`, `clock`).
- `srand(clock());`: don't mind this line too much, its purpose is to [seed](seed.md) a pseudorandom number generator. Without doing this the game would always generate the same sequence of random numbers when run again.
- `while (1)` is an infinite game loop -- it runs over and over, in each cycle we perform one game round. The loop can be exited with the `break` statement later on (if the user answers he doesn't want to continue playing).
- `int randomNumber = rand() % 10;`: this line declares a variable named `randomNumber` and immediately assigns a value to it. The value is a random number from 0 to 9. This is achieved with a function `rand` (from the above included `stdlib` library) which returns a random number, and with the modulo (remainder after division) arithmetic operator (`%`) which ensures the number is in the correct range (less than 10).
- `int guess;` creates another variable in which we'll store the user's guessed number.
- `scanf("%d",&guess);` reads a number from the input to the variable named `guess`. Again, don't be bothered by the complicated structure of this command, for now just accept that this is how it's done.
- `getchar();`: don't mind this line, it just discards a newline character read from the input.
- `if (guess == randomNumber) ...`: this is a branch which checks if the user guess is equal to the generated random number. If so, a success message is printed out. If not, a fail message is printed out along with the secret number. Note we use the `puts` function for the first message as it only prints a text sting, while for the latter message we have to use `printf`, a more complex function, because that requires inserting a number into the printed string. More on these functions later.
- `char answer;` declares a variable to store user's answer to a question of whether to play on. It is of `char` data type which can store a single text character.
- `scanf("%c",&answer);` reads a single character from input to the `answer` variable.
- `if (answer == 'n') break;` is a branch that exits the infinite loop with `break` statement if the answer entered was `n` (*no*).
## Functions
## Header Files, Libraries, Compilation
## Advanced Data Types
## Macros
## Pointers
## Recursion
## Dynamic Allocation
## Debugging
## Advanced Stuff
## Under The Hood