Première séance
Durant cette première séance, nous allons écrire de petits programmes qui écrivent dans le terminal. Le but est d'apprendre :
- à compiler un seul fichier C (un seul fichier pour l'instant !)
- écrire un programme C sans pointeur
Header files
Des fichiers comme stdio.h
sont dans usr/include
. Ils contiennent des signatures de fonctions. Ils font partie de la bibliothèque standard. Mais on peut aussi en créer, ou utiliser ceux d'une bibliothèque non-standard (comme raylib
pour dessiner à l'écran !).
Entrées-sorties
stdio.h
est le fichier pour de la bibliothèque standard (std
) pour les entrées-sorties (io
).
Pour utiliser ces fonctions, on écrit :
#include <stdio.h>
Ecrire sur la sortie stdout
putchar('c')
écrit un c
dans le terminal.
printf
est la fonction pour écrire d'un coup des informations plus compliquées ✎ :
printf("Bonjour");
printf("Bonjour\n");
printf("Voici votre identifiant : %d", id);
printf("Voici votre nouveau prénom : %s", prenom);
printf("Voici votre nouveau prénom et votre identifiant : %s %d", prenom, id);
⚠ Ne jamais écrire printf(dataFromTheUser)
car l'utilisateur pourrait écrire des %s
, %d
, voire des %n
qui écrivent dans la mémoire. Le comportement peut être inattendu, et c'est faille de sécurité garantie :).
Lire l'entrée stdin
getchar()
renvoie le prochain caractère sur l'entrée puis le consomme, c'est-à-dire que la prochaine fois que l'on exécute getchar()
on lira le prochain caractère. getchar()
renvoie EOF
si c'est fini.
scanf
est la fonction pour lire des informations plus compliquées que l'utilisateur écrit dans la console ou de manière générale dans stdin
⌨ :
int n;
scanf("%d", &n);
Quelques éléments du langage C
Une déclaration de variable est un morceau de code qui renseigne le type d'une variable. Par exemple :
int x;
Il y a pleins de types primitifs : int
, long
, unsigned int
, char
, bool
(avec #include <stdbool.h>
).
Une instruction est un morceau du programme qui ne renvoie rien. Par exemple, printf("aïe");
Une expression est un morceau du programme qui renvoie une valeur. Par exemple 1+2
. Mais aussi x = 42
qui renvoie... 42
.
Incrémentation
Considérons l'instruction (qui est aussi une expression)
x = 42;
- Both expressions
x++
and++x
incrementx
. - The value of the expression
x++
is 42. - The value of expression
++x
is 43.
L'instruction (qui est aussi une expression) suivante
x += 3;
ajoute 3 à x.
Boucle for
for(int i = 0; i < n; i++)
...
for(int i = 0; i < n; i++) {
...
}
En fait, la boucle for
en C est puissante. Elle a l'expressivité des boucles while
:
for(expr1; expr2; expr3) {
...
}
est équivalent à
expr1;
while(expr2) {
...
expr3;
}
La fonction main
Un programme C contient toujours une fonction main
qui est la fonction appelée quand on exécute le programme :
#include <stdlib.h>
int main() {
...
return EXIT_SUCCESS;
}
On verra plus tard une signature plus compliquée pour main
car on peut gérer des arguments donnés au programme.
Utilisation du compilateur
gcc -Wall -pedantic -ainsi -std=c99 programme.c -o programme
Options | Meaning |
---|---|
-Wall | enables all compiler's warning messages |
-Wextra | still a bit more warnings |
-pedantic | enables all compiler's warning messages |
-ansi | turns off gcc features that are not in the ANSI C |
-std=c99 | ANSI C99 |
-std=c11 | ANSI C99 |
-o programme | tells that the output is the file programme |
Exercices
Triangle d'étoiles
Ecrire un programme qui prend demande à l'utilisateur/rice un nombre entier n
puis affiche un triangle d'étoiles sur n
lignes. Par exemple si n
vaut 5, on affiche :
*
**
***
****
*****
Pyramide
Même chose avec une pyramide :
*
***
*****
*******
Nombre de caractères dans le texte sur stdin
En utilisant getchar()
, écrire un programme nombreligne.c
qui lit stdin
et sur donne le nombre de lignes dans l'entrée.
Par exemple sur
./nombreligne < textExemple.txt
il donne le nombre de lignes dans le fichier texte textExemple.txt
.
- Pareil avec le nombre de lignes
- Pareil avec le nombre de mots
Occurrences de caractères
Dans cet exercice, vous aurez besoin d'un tableau d'entiers de taille 26 déclaré avec int A[26];
. On accède au i
-ème élément du tableau A
avec A[i]
. On rappelle que chaque caractère est un nombre entre 0 et 255, codé sur 8 bits. Si c
est un char
, on peut écrire c - 'a'
pour faire la différence entre le code de c
et celui de la lettre 'a'
.
Ecrire un programme qui lit stdin
et qui affiche un histogramme du nombre des occurrences des lettres (on ignore les autres caractères, les chiffres, etc.) comme :
a ***
b ******
c **
d *
e ************
z ***
Variables
La portée (scope) d'une variable est la portion de code dans laquelle la variable peut être utilisée.
La durée de vie (life-time) d'une variable est la durée d'existence d'une variable.
Scope | Life-time | |
---|---|---|
Global variables | All | Always |
Variables in functions | Function | Function |
Static variables in functions | Function | Always |
Les variables statiques peuvent servir pour :
- faire un compteur et cacher le contenu du compteur en dehors
- faire une fonction pour le drag drop avec la souris (on stocke/cache la position précédente de la souris)
Mémoire
La mémoire allouée pour un programme est divisée en trois parties :
- Segment de données. On y trouve les variables globales et les variables statiques.
- Pile d'appels. On y trouve les variables locales à une fonction. Les tableaux locaux sont stockées sur la pile aussi.
- Le tas mémoire. C'est pour y mettre des données dont on ne connait pas à l'avance la taille, ou dont la taille peut modifiée au cours du programme (structure de données comme des tableaux redimensionnables, des listes chaînées, etc.).
Typage en C
Le type en C sert à dire combien d'octets prend une variable.
La fonction sizeof
renvoie combien d'octets sont utilisé pour stocker un certain type / une certaine variable.
sizeof(truc) | utilise ... octets |
---|---|
sizeof(char) | 1 |
sizeof(int) | 4 |
int x;
printf("%d\n", sizeof(x));
int A[5];
printf("%d\n", sizeof(A));
Conversion implicite
1 + 2.3f
Casting
int i = 2;
int j = 3;
float quotient = 2/3;
Oh non, quotient
vaut 0. Mais on peut caster :
quotient = ((float) 2) / 3
Le C est de bas niveau...
Voici un site où on peut compiler du code C et voir le résultat en assembleur :
https://godbolt.org/
Exercices
Génération de labyrinthes
Proposer un algorithme aléatoire pour générer un labyrinthe comme
XXXXXXXXXXXXXXX
X X X X
X XXX X X X XXX
X X X X X X
X X XXXXX XXX X
X X X X X
X X X X XXXXX X
X X X X X X X
X XXX X X X X X
X X X X X X
X X XXX X XXX X
X X X X X X
X XXXXXXX X X X
X X X
XXXXXXXXXXXXXXX
Il s'agit de produire un tableau A 2D de taille n x m où n et m sont des entiers impairs avec :
- A[i, j] =
'X'
ou' '
- A[0, j], A[i, 0], A[n-1, j], A[i, m-1] contiennent
'X'
; - A[i, j] =
'X'
lorsque i et j sont pairs - A[i, j] =
' '
lorsque i et j sont impairs - Le graphe G est un arbre, où G est le graphe non orienté (V, E) où V sont les couples (i, j) dans {1, 3, .., n-2} x {1, 3, ..., m-2} et E contient les arêtes {(i, j), (i', j')} avec :
- i' == i+2 et j'== j et A[i+1, j] ==
' '
- ou i' == i et j' == j+1 et A[i, j+1] ==
' '
Prochaine séance
Nous allons utiliser la bibliothèque raylib
pour pouvoir afficher des dessins (rectangles, points, lignes, etc.) à l'écran :).
- Jeu vidéo comme
agar.io
- Afficher une fractale comme celle de mandelbrot
- Promenade aléatoire
- Appartenance d'un point à un polygone ?
- parcours de Graham
Pour aller plus loin
- https://emscripten.org/ Pour développer des programmes qui tournent sur le Web
- https://cs50.readthedocs.io/style/c/
- https://www.gnu.org/prep/standards/html_node/Writing-C.html#Writing-C
- Fonctions de base en langage C sur wikiversité
- Du matériel sur la génération de labyrinthes