Précédent Remonter Suivant

2.1  Premier programme en C

Commençons par un grand classique. Ainsi, on se propose tout d'abord d'afficher quelque chose à l'écran. Le bout de code suivant va réaliser cette tâche.
#include <stdio.h>

/* ceci est un commentaire */

/* ceci est un commentaire 
   sur plusieurs ligne     */

int main(void) {
  /* pas de declaration 
     de variable locale */
  printf("Salut le monde\n") ; 
  return 0 ; /* instruction de retour */
}

 
Dans cette exemple, on peut remarquer que les expressions en C se terminent par un point-virgule et qu'un commentaire commence par /* et se termine par */. Ainsi, on peut placer la ligne suivante
/*  Ceci est un commentaire */
dans un programme C sans affecter son comportement.

Avant d'exécuter notre programme, précisons quelques points de théorie.

2.1.1  C est un langage compilé

Cela signifie qu'un programme C est décrit par un fichier texte appelé fichier source. Ce fichier n'est pas exécutable par le microprocesseur, il faut le traduire en langage machine. Cette opération est effectuée par un programme appelé compilateur. La compilation se décompose en 4 phases successives :
  1. Le traitement par le préprocesseur :le fichier source est analysé par un programme appelé préprocesseur qui effectue des transformations purement textuelles (remplacement de chaînes de caractères, inclusion d'autres fichiers source, etc.) ;
  2. La compilation : au cours de cette étape, le fichier engendré par le préprocesseur est traduit en assembleur, c'est à dire en une suite d'instructions qui sont chacunes associées à une fonctionnalité du microprocesseur (faire une addition, une comparaison, etc.) ;
  3. L'assemblage : cette opération transforme le code assembleur en un fichier binaire, c'est à dire en instructions directement compréhensibles par le processeur. Le fichier produit par l'assemblage est appelé fichier objet ;
  4. L'édition de liens : un programme est souvent séparé en plusieurs fichiers source (ceci permet d'utiliser des librairies de fonctions standard déjà écrites comme les fonctions d'affichage par exemple). Une fois le code source assemblé, il faut donc lier entre eux les différents fichiers objets. L'édition de liens produit alors un fichier exécutable.
Comme rien ne vaut la pratique, nous allons effectuer les tâches décrites ci-dessus.

2.1.2  Compilation par la pratique

Édition du fichier source
Pour éditer le fichier source, nous allons utiliser le logiciel emacs que l'on lance depuis le shell par la commande $ emacs.

Pour éditer un fichier source, utiliser la barre de menu d'emacs :
File -> Open,

puis indiquer un nom de fichier avec la lettre c pour extension --- foo.c par exemple. Emacs vous présente un buffer dans lequel vous pouvez créer votre fichier source (dans notre cas, il s'agit de la procédure permettant l'affichage d'un message présenté en début de section 2.1)
Compilation.
Une fois que l'édition de votre fichier source est terminée, vous pouvez le compiler. Dans notre cas, nous utilisons le compilateur gcc. On utilise dans le shell la commande $ gcc foo.c et on obtient directement le fichier exécutable a.out. Le nom du fichier exécutable peut être spécifié en utilisant l'option -o du compilateur (gcc -o nom_de_l_executable foo.c). De plus, l'option -Wall permet d'afficher tous les avertissements émis par le compilateur. Les options -ansi -pedantic permettent de faire signaler tout ce qui s'écarte de la norme dans votre programme.
Exécution.
Enfin pour finir, on peut exécuter à partir du shell le fichier résultant par la commande $ a.out.
Expérimentation
On peut suivre les étapes de la compilation en utilisant les options adéquates du gnu c compiler. Ainsi. Plus généralement, la commande man gcc fournit le manuel du compilateur gnu.

Remarque. En guise de conclusion, il faut bien retenir que seuls les fichiers source doivent être archivés.




Exercice 2.0 --- Valeur de retour.


Considérons le programme :
int main(void){
  return 5 ;
}
Ce programme est uniquement constitué par la fonction principale main qui ne prend aucun paramètre et retourne l'entier 5.

Compiler ce programme afin d'obtenir un fichier exécutable foo. Vous pouvez lancer son exécution depuis le shell et récupérer sa valeur de retour par la commande interne echo en affichant la variable ?.
% foo 
% echo $?
Que constatez vous ? Confirmez votre intuition en faisant varier la valeur de retour.







Exercice 2.1 --- Étapes de la compilation.


Nous allons utiliser le programme suivant :
#include <stdio.h>
#define MAX 3
const int bar_constante = MAX ;
int foo_global = 1 ;

extern int bar ;

int main(void) {
  int foo_local = 2 ;
  printf("Salut le monde~: %d \n",bar + foo_global + foo_local) ; 
  return 0 ;
}
La compilation se fait avec gcc dont l'aide est disponible en ligne. Cette aide est structurée en section ; les informations nous intéressant dans cet exercice se trouvent dans la section OPTIONS, sous-section Options contrôlant le type de sortie après la description des options concernant les langages compris par gcc.
Questions.
  1. Combien de lignes non vide le préprocesseur a-t-il ajouté à votre code ? (Ne comptez pas, utilisez des outils shell dont wc).
  2. Qu'est devenu la ligne #include <stdio.h> ? Que sont devenus les commentaires ? Comment a été traitée la chaîne ce caractères MAX ?
  3. Pour examiner un fichier objet, vous pouvez utiliser objdump ou nm. Dans la table des symboles, quels sont les références qui seront résolues par l'éditeur de liens ? En utilisant l'utilitaire ldd, déterminer quels sont les fichiers objets utilisés par votre exécutable ? (Pour achever la compilation supprimer la variable externe bar de votre code).





Pour tout commentaire : Alexandre Sedoglavic.
Précédent Remonter Suivant