Langage C

danger !

Le C est un langage de bas niveau et fait pour être exécuté rapidement. Les conséquences sont :

  • il vous permet de tout faire
  • il ne vérifie pas vos actions

Il y a donc quelques règles à respecter pour se simplifier la tâche de développement :

  • être explicite
    • pas de magic number
    • typage explicite
  • on ne fait pas le malin :
    • avec le préprocesseur
    • avec les subtilités syntaxiques du langage

Le C est organisé autour d'une fonction principale appelée main.

Cette fonction va contenir le corps du programme. Elle peut être définie de plusieurs manière, nous utiliserons en majorité celle ci :

int main (){

  return 0;
}

Toutes les fonctions que l'on ne définira pas seront ajoutée dans la partie édition de lien. Pour que le compilateur soit content il faudra que leur signature soit définie, ceci se fait via les instructions préprocesseur #include <nomlib.h> qui incluent les headers de la bibliothèque utilisée.

L'exemple minimal est celui donné précédemment :

#include <stdio.h>

int main() { 
    printf("Hello World!\n");

    return 0; 
}

Qui utilise la fonction de la libc printf dont la signature est définie dans le fichier de header stdio.h.

Commentaires

Deux types de commentaires.

Sur plusieurs lignes :

/* un commentaire sur 

plusieurs

lignes

*/

Tout ce qui est entre /* et */ est ignoré

danger !

Les commentaires ne peuvent être imbriqués :


/* /* */ */

N'est pas un commentaire valide en C.

Sur une ligne :

// commentaire sur une ligne

Tout ce qui est après // sur la même ligne est ignoré.

Bases

Types de données

Fonctions

Structures de contrôle

Pointeurs

Types dérivés

Les types dérivés sont des collections de types de base (entier, réel, caractère ou pointeur).

Tableaux

Chaînes de caractères

Structures

enum

Le C permet aussi d'utiliser des enum pour gérer des modalités discrètes.

Types complexes

Gestion de la mémoire

Ligne de commande

Pour utiliser les paramètres du programme, on peut écrire la fonction main ainsi :

int main(int argc, char *argv[argc+1]) {

for (size_t i = 0; i < argc; i++) {
     printf("l'argument numéro %d vaut %s", i, argv[i]);
 }

}

Vous verrez aussi les signatures suivantes, équivalentes :

Obtenir les valeurs d'une variable d'environnement peut se faire avec la fonction getenv de la libc (définie dans <stdlib.h>) :

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {

for (size_t i = 0; i < argc; i++) {
     printf("l'argument numéro %d vaut %s", i, argv[i]);
 }

const char* s = getenv("PATH");
printf("PATH :%s\n", (s != NULL) ? s : "pas de PATH défini");

}

Règles

Attention aux Undefined Behavior (UB) résultant d'erreur de code qui font que :

Voir par exemple ce court tuto ou celui-ci (un peu plus long)

Cela rend le déboguage très difficile. Il faut donc toujours essayer d'être le plus explicite possible et surtout rester simple.