Previous Up Next

2  Premiers pas en C

Il est d’usage d’écrire un programme «hello world». En voici une version un peu différente.


Exercice 15
 (Édition de code)   Avec emacs, ouvrez le fichier prog1.c présent dans votre dépôt git et dont les premières lignes sont
/* Ceci est un commentaire */

/**
 * Nous allons utiliser la fonction "putchar()" de la librairie 
 * standard du langage C pour sortir le caractère de code ASCII
 * "c" sur le terminal. Cette fonction retourne -1 en cas d'ereur.
 * Voici la déclaration de cette fonction :
 **/
extern int putchar (int c);

/**
 * Nous définissons maintenant la fonction "main()" : nous allons 
 * écrire le corps de cette fonction.
 * "main()" est la fonction qui sera exécutée au démarrage de 
 * notre programme.
 * Cette fonction ne prend pas de paramètre et retourne 0 si le
 * programme termine correctement (une autre valeur en cas d'erreur).
 **/
int
main()
  {
 putchar(72);
 ...

Notez que ce code choisit délibérément une indentation fantaisiste. Cette écriture peut sembler particulièrement dissonante pour des informaticiens habitués à programmer en Python. Cependant contrairement à Python le langage C n’impose pas d’indentation a priori. Ceci étant dit, une indentation fantaisiste complique la lecture d’un programme, aussi avec le temps, diverses stratégies d’indentations ont été proposés, les styles : K&R, BSD KNF, GNU... Consultez éventuellement la page https://en.wikipedia.org/wiki/Indentation_style.

Les éditeurs de code source proposent souvent des options de normaliser l’indentation d’un fichier ou d’une sélection de texte, automatiquement.


Exercice 16
 (Indentation)   Trouvez dans la carte de référence emacs un moyen de reprendre l’indentation du code C que vous avez saisi. Reformatez ainsi tout le code source du fichier prog1.c.

Ensuite, réalisez un commit pour enregistrer cette modification dans votre dépôt Git. Ce commit devra être accompagné d’un message bref et pertinent, décrivant la modification réalisée (exemple: "correction de l’indentation").

De manière générale, vous devrez réaliser un commit pour chaque exercice en TP de PdC (même si l’énoncé de l’exercice ne le demande pas explicitement). Pensez également à faire un push à la fin de la séance.


Exercice 17
 (Mise en commentaires)   Sachant que sous emacs la commande <M-;> est relative à la mise en commentaire, commentez la fonction main(), puis décommentez la.

La fonction putchar() prend en paramètre une valeur appelée c qui est déclarée de type int. Ce type int en C ne signifie pas exactement «entier». En fonction des caractéristiques du microprocesseur, une valeur N est choisie par le compilateur C2, et int signifie «mot mémoire de la machine pour manipuler des entiers dans l’intervalle [−2N..2N−1]».

Dans cet exemple de programme, observez que la fonction putchar() assume que la valeur de c sera un «code ASCII», donc une valeur comprise entre 0 et 255 qui est associée à un caractère alphanumérique. C’est bien ce caractère, et non la valeur entière utilisée pour le coder, qui sera affichée sur le terminal3 .

Dans la fonction main() figurent différentes manières d’exprimer une valeur littérale entière en C :

  1. 72 correspond à la valeur décimale 72 ;
  2. 0x69 représente la valeur hexadécimale 69, ce qui est équivalent à la valeur décimale 105 (6 × 16 + 9 = 105) ;
  3. ’!’ représente la valeur du code ASCII du caractère «!», soit la valeur décimale 33. Consultez éventuellement la page de manuel man ascii pour vous en convaincre.
  4. ’\n’ représente la valeur du code ASCII du caractère associé à line feed, retour à la ligne, ce qui est équivalent à la valeur décimale 10.

Exercice 18
 (Valeurs littérales et code ASCII)   Quelle succession de quatre caractères l’exécution du programme principal va-t-elle afficher ?

Exercice 19
 (Compilation)   Listez les fichiers présents dans votre répertoire courant avec la commande ls. Assurez vous que votre fichier source est bien présent.

Pour compiler ce programme prog1.c, il suffit de lancer la commande suivante :

bash$ gcc prog1.c
bash$

Dans votre répertoire courant, lister à nouveau les fichiers présents. Quel fichier l’exécution de gcc a créé ?


Exercice 20
 (Exécution)   Lancer l’exécution du fichier créé. Ajouter événtuellement ./ devant son nom, pour que bash le trouve.

Comparez l’affichage à la réponse que vous aviez fournis à l’execice 18. Que pouvez-vous en dire ?

Nous allons maintenant implémenter une nouvelle fonction : newline().

Cette fonction imprime simplement un line feed pour forcer l’affichage à passer à la ligne. Comme putchar(), elle retourne -1 si elle n’a pas pu produire l’octet en sortie, ou une autre valeur sinon.


Exercice 21
 (Une fonction)   Pour définir cette fonction saisissez le code suivant à la fin de votre fichier :
 
int
newline()
{
    return putchar('\n');
}
Puis appelez la fonction newline() à la place de putchar(’\n’) dans le programme principal.

Compilez votre programme et exécutez le.

Qu’observez-vous ?

Rappel : n’oubliez pas de réaliser le commit correspondant à cet exercice. Ceci ne sera plus rappelé sur les exercices suivants.

La compilation d’un source C est une opération «en flux». C’est-à-dire que le compilateur traite une ligne de source avant de passer à la suivante. Lorsque un source utilise une fonction avant que le corps de cette fonction n’ait été traité par le compilateur, ce dernier déclare qu’elle n’existe pas. Dans le doute gcc «suppose» l’existence d’une fonction implémentée plus tard, mais il génère une alerte (warning) : il signale que, même s’il a fait au mieux, il y a un problème dans le code source.

Pour éviter ce warning, vous pouvez bien sur déplacer le code de la fonction newline() avant l’implémentation de la fonction main().

Cependant il peut parfois être nécessaire ou simplement souhaitable de ne pas imposer au développeur un ordre particulier dans l’implémentation des fonctions d’un programme.

Aussi il est possible de déclarer dans un premier temps l’existence d’une fonction, sans en donner le code. Si une telle déclaration est donnée avant que le compilateur ne traite la fonction main(), lorsqu’il compilera cette dernière il ne génèrera pas de warning.


Exercice 22
 (Déclaration de fonction)   En tête de votre fichier source, donnez la déclaration de la fonction newline() mais pas son implémentation. De la même manière que nous avons donné la déclaration de la fonction putchar(). En C on appelle prototypes ces déclarations de fonctions qui ne donnent pas le corps.

Recompilez votre programme et assurez vous que le warning a disparu.


Previous Up Next