Il est d’usage d’écrire un programme «hello world». En voici une version un peu différente.
/* 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.
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.
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 :
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éé ?
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.
Puis appelez la fonction newline() à la place de putchar(’\n’) dans le programme principal.int newline() { return putchar('\n'); }
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.
Recompilez votre programme et assurez vous que le warning a disparu.