Je suppose que vous vous êtes tous déjà demandés le comment de la conception d'un programme. Vous avez déjà vaguement entendus parler des langages de programmation et de cet instrument magique qu'est le compilateur qui transforme votre joli code en un affreux fichier binaire illisible (appelé éxécutable sous Windows). Hé bien ne cherchez plus mes frères ! Ici, le graal de l'informatique, la chaîne de compilation, vous sera expliqué !
Voici un simple programme en C, le traditionnel "Hello World" (je vais expliquer la chaîne de compilation utilisée par le compilateur libre GCC (GNU C Compiler), du projet GNU, mais tous les compilateurs utilisent globalement la même méthode) :
Code :
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("Hello world !\n");
return EXIT_SUCCESS;
}
Commençons par une analyse de ce petit programme pour les non-codeurs :
Code :
#include<stdio.h>
#include<stdlib.h>
Ce sont ce que l'on appelle des
directives de ompilation. Il en existe beaucoup d'autre mais la directive
include est la plus fréquente car elle permet d'
inclure un autre fichier, i.e. de mettre "à la place" le texte d'un autre fichier.
Dans le cas présent, le programme inclut des
librairies externes car le nom des fichiers inclus (
stdio.h et
stdlib.h) sont entre '<' et '>'. Le compilateur va donc aller chercher les fichiers dans tous les dossiers décrits dans la
variable d'environnement PATH (chemin en français), à la différence d'une directive
include entre double quotes (") pour laquelle le compilateur chercherait le fichier dans le repertoire en cours ; bien entendu, il est également possible d'inclure des fichier .h (comme
header (en-tête en Français)) dans des sous-dossiers. Exemple :
Code :
#include "my_file.h"
#include "dossier\file2.h"
#include "dossier/file3.h"
Le premier
include va inclure le fichier "my_file.h" du dossier du projet. Le deuxième va inclure le fichier "file2.h" du sous-dossier judicieusement appelé "dossier". Quant au troisième, il va inclure le fichier "file3" du même dossier. La différence tient dans le fait que le séparateur est un '/' (slash) au lieu d'un '\' (backslash ou encore antislash (bêrk !) ). Traditionellement, sous Windows, on utilise un backslash pour une arborescence, mais tous les autres
OS (Operating System - Système d'exploitation) uilisent un simple slash. Cependant, Windows convertit automatiquement les slash en backslash ; pour des raisons de
portabilité du code (le fait de porte un code d'un OS à un autre), il est donc fortement conseillé de mettre des slash (en plus, c'est plus joli).
Une
variable d'environnement est, comme son nom l'indique une variable accessible par tous les programmes. En général, sous Windows, on n'ignore jusqu'à leur existence pas car l'utilisateur "de base" n'en a pas l'utilité, mais elles sont bien là . Pour y accéder (sous Windows NT4/2K/XP), il faut aller dans : Panneau de configuration -> Système -> Onglet "Avancé" -> Bouton "Variables d'environnement". Un conseil : N'Y TOUCHEZ PAS !!! Cela risquerait de rendre votre système complètement inutilisable.
Code :
int main()
{
printf("Hello world !\n");
return EXIT_SUCCESS;
}
Attaquons maintenant la partie difficile.
Code :
int main()
{
...
}
Cela est ce que l'on appelle une
fonction. En C, la fonction
main est obligatoire, son contenu est ce que va faire le programme. Si cette fonction est absente, le programme ne peut pas compiler. Pour bien comprendre le concept de fonction, il est préférable de prendre un modèle plus "général" :
Code :
int ajout (int a, int b)
{
return a+b;
}
Code :
int ajout (int a, int b)
Il s'agit de l'
en-tête de la fonction, la seule chose dont un utilisateur externe a besoin de savoir. Cette fonction s'apelle
ajout, elle prend en paramètres 2 entiers (c'est le (int a, int b),
int est l'abréviation de integer (entier) ) judicieusement appelés a et b et renvoie un autre entier (c'est le premier int, en début de ligne).
Code :
{
return a+b;
}
Il s'agit du corps de la fonction. Il contient son code. Il n'y a ici qu'une seule ligne de code. Le
mot-clé ou
mot réservé return indique la valeur de retour de la fonction. Dans le cas présent,
ajout renvoie le résultat de l'addition de a par b, tout simplement.
Mais revenons à nos moutons (Bêêêêhh !).
La fonction
main ne prend aucun paramètre (ce n'est pas toujours le cas) et renvoie un entier qui est le
code de sortie du programme.
Code :
{
printf("Hello world !\n");
return EXIT_SUCCESS;
}
Code :
printf("Hello world !\n");
Cette ligne de code contient un appel à la fonction printf de la
bibliothèque d'entrée/sortie standard. Toutes les fonctions, procédures et constantes de cette biliothèque sont déclarées dans le fichier
stdio.h.
La fonction printf affiche une chaîne de caractère formatée (i.e. on peut lui indiquer d'afficher des entiers, des flottants, des caractères, des pointeurs ou n'importe quella variable ou constante de type standard) sur la
sortie standard : la console.
La partie située entre double-quotes (") est une
chaîne de caractères en C, concrètement, il s'agit d'un tableau de caractères codés en
ASCII, dont voici la table (un caractère est en fait un entier codé sur 8 bits) :

Comme on peut le constater, les caractères n'utilisent que 7 bits : le bit de poids fort (celui le plus à gauche quand on écrit) est toujours à 0. Si ce bit est à 1, on entre dans la table étendue qui dépend du système, il s'agit en général de l'
ISO8859-15 (caractères accentués courants et symbole euro). Pour plus d'infos, votre ami dévoué Wikipedia :
http://fr.wikipedia.org/wiki/ISO_8859-15. Notez qu'il existe d'autres manières d'encoder les caractères, en particulier l'
Unicode, très utilisé pour les jeux de caractères comportant un grand nombre de symboles (Japonais, chinois...). Mais l'
ASCII, malgré ses limites, reste le plus utilisé.
'\n', bien que composé de 2 caractères est un caractère à part entière : il symbolise un
retour chariot.
Code :
return EXIT_SUCCESS;
Comme vu plus haut, il s'agit de la fin de la fonction : ce qu'elle retourne. Ici, elle renvoie la valeur
EXIT_SUCCESS définie dans la
librairie standard, dont les fonctions, procédures et constantes qui regroupent notamment la gestion de la mémoire sont définies dans
stdlib.h.
EXIT_SUCCESS est une constante définie dans ce fichier, c'est le code de sortie d'un programme se terminant normalement, par opposition à
EXIT_FAILURE qui indique qu'une erreur s'est produite, en théorie... En effet, on n'utilise que rarement dans les faits ces 2 valeurs et on préfère écrire directement
return 0 ou
return 1 (c'est ce que valent ces constantes, si ma mémoire est bonne).
Une constante est définie à l'aide d'une directive de compilation :
Code :
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
Au moment de la comspilation, le compilateur va commence par remplace toutes les occurences de
EXIT_SUCCESS par 0 et toutes les occurences de
EXIT_FAILURE par 1.
Bien ! C'est tout pour aujourd'hui, je m'attaquerai à la chaîne de comspilation en elle-même une autre fois. il me semblait important de bien expliquer d'abord rapidement (TRES rapidement !) le fonctionnement et la syntaxe du langage C.