Leçons de niveau 15

Langage C/Rencontre avec le C

Une page de Wikiversité.
Sauter à la navigation Sauter à la recherche
Début de la boite de navigation du chapitre
Rencontre avec le C
Icône de la faculté
Chapitre no 3
Leçon : Langage C
Chap. préc. :Outils
Chap. suiv. :Variables
fin de la boite de navigation du chapitre
Icon falscher Titel.svg
En raison de limitations techniques, la typographie souhaitable du titre, « Langage C : Rencontre avec le C
Langage C/Rencontre avec le C
 », n'a pu être restituée correctement ci-dessus.

Maintenant que vous vous êtes fait une vague idée de ce que permet la programmation et que vous avez tous les outils en main, il est temps de se lancer dans l'écriture de notre premier programme. Ce chapitre vous permettras de vous familiariser avec la programmation par la découverte de nombreux éléments ainsi qu'un vocabulaire particulier qui vous est peut-être totalement inconnu. La plupart des notions qui seront traités dans ce chapitre sont applicables à de nombreux langages de programmation, et si le C n’est pas le premier langage que vous apprenez alors il est fort probable que cette partie du cours vous paraisse très simple. Néanmoins, il est important de lire très attentivement ce chapitre car il vous présentera entre autres la syntaxe et les éléments essentiels à tout programme en C.

Ce que l’on va réaliser[modifier | modifier le wikicode]

Avant d'écrire un programme, il faut être au courant de ce que l’on veux et peux faire. Or, pour l'instant nos connaissances en programmation sont plus que limitées, et il est vain de croire que vous allez pouvoir créer le dernier jeu vidéo à la mode, ou un logiciel révolutionnaire en quelques jours de pratique. En effet, l'apprentissage du C est long, et il vous faudra entre quelques semaine et quelques mois selon votre assiduité et votre sérieux pour réaliser des programmes dit « graphiques ». Il existe en effet deux types de programmes : les programmes graphiques et les programmes en console.

Les programmes graphiques[modifier | modifier le wikicode]

Les programmes graphiques sont probablement les seuls que vous manipulez si votre machine est sous Windows ou Mac OS X. Vous en avez rencontré énormément, peut-être sans le savoir : votre lecteur multimédia, votre navigateur Web, votre logiciel de discussion instantanée, votre suite bureautique, vos jeux vidéos sont des programmes graphiques, autrement appelés programmes GUI. En voici un exemple sous Windows 8 :

VLC version 2.1.0 on Windows 8

Cependant, écrire ce genre de programmes demande beaucoup de connaissances, il faut savoir manier les bibliothèques, les tableaux, les fonctions, bref, savoir programmer. Pour l'instant, c’est bien trop compliqué pour nous. Il faut donc se rabattre sur le deuxième type de programme : les programmes en console.

Les programmes en console[modifier | modifier le wikicode]

Les programmes en console sont les seuls qui existaient dans les débuts de l'informatique (certains d’entre vous se souviennent peut-être de MS-DOS), mais ont fini par être remplacés par des programmes munis d'une interface graphique avec les sorties de Windows et de Mac OS. Cependant, s'ils peuvent sembler totalement désuets de nos jours, ceux-ci sont toujours utilisés sur des systèmes UNIX tel que GNU/Linux en raison des performances qu’ils offrent notamment sur les tâches répétitives.

Voici un exemple de programme en console :

12 - 7 = 5
Right!
9 - 5 = 4
Right!
1 + 5 = 6
Right!
3 + 3 = 6
Right!
5 + 4 = 9
Right!
10 + 9 = 19
Right!
16 - 10 = 6
Right!
9 - 1 = 8
Right!
18 - 10 = 8
Right!
3 + 3 = 6
Right!


Rights 10; Wrongs 0; Score 100%
Total time 16 seconds; 1.6 seconds per problem

Press RETURN to continue...

Dans un premier temps, ce sera le seul type de programme que nous allons créer. Rassurez-vous, vous pourrez bien entendu créer des programmes dotés d'une interface graphique en suivant ce cours car vous saurez utiliser d’autres bibliothèques, et pourrez ainsi créer tout ce qui vous passe par la tête.

Analyse du code minimal[modifier | modifier le wikicode]

Dans le chapitre précédent, nous avons installé tous les outils nécessaires à la programmation en C et nous avons compilé notre premier code source. Il est temps de découvrir plus en détail ce code et de comprendre ce qu’il signifie. Petite touche culturelle : ce code minimal a été créé par Dennis Ritchie, l’inventeur du C. Aujourd’hui beaucoup d’IDE, peu importe le langage, proposent un code semblable à celui-ci pour démarrer.

Je remets ce code ici pour que tout le monde aie le même :

#include <stdio.h>

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

    return 0;
}

Si le code présent dans votre éditeur est différent de celui-ci, remplacer le, il est important que nous ayons le même. N'oubliez pas de sauvegardez même si le projet ne contient pas grand chose, c’est une bonne habitude à prendre et ça vous éviteras un bon nombre de mésaventures.

#include[modifier | modifier le wikicode]

On retrouve la ligne suivante tout en haut du programme :

#include <stdio.h>

C'est une directive de préprocesseur, facilement reconnaissable car elles commencent toutes par un #. Dans le cas présent, elle permet de charger des fichiers contenant des « morceaux de code » tout prêt qui permettent de réaliser de nombreuses actions basiques (afficher un message à l'écran, lire un fichier externe, quitter le programme, etc). En effet, sans ces morceaux de code, appelés fichiers d’en-tête (en anglais, on parle de headers), le C ne sait pratiquement rien faire. On dit que c’est un langage modulaire.

L’ensemble de ces fichiers d'en-tête est appelé bibliothèque de l'anglais « library » (Le mot « library » se traduit bien par « bibliothèque », et non « librairie »).

Dans notre cas, nous ne chargeons qu'un seul fichier d'en-tête : stdio.h, qui signifie « Standard input output », soit « Entrée-sortie standard ». Ce fichier d'en-tête va nous permettre de communiquer avec l'utilisateur en affichant des messages à l'écran et en récupérant les informations que celui-ci pourrait entrer.

int main(void)[modifier | modifier le wikicode]

La partie suivante constitue le cœur du programme :

int main(void)
{
    
}

Ce bout de code constitue une fonction, dans le cas présent, c’est la fonction main (prononcez « mèïne ») qui est représentée. Un programme en C se compose en grande majorité de fonctions, qui sont un ensemble d'instructions que l’on peux appeler à n’importe quel moment dans le programme. La fonction main est la fonction principale de tout programme écris en C, le programme commence en suivant les instructions contenues dans cette fonction et se termine après avoir atteint la fin de celle-ci. En théorie, il donc possible d'écrire tout notre programme dans cette fonction main, néanmoins, les programmes que vous allez réaliser vont très rapidement se complexifier, et il sera alors primordial d'organiser son code en plusieurs fonctions intelligemment choisies. Par exemple, si notre programme nécessite à plusieurs reprises de calculer la racine carrée d'un nombre, il peut-être judicieux de créer une fonction calculer_racine_carree à qui l’on transmettra un nombre et qui nous renverra la racine carrée de celui-ci.

Une fonction est délimitée par des accolades ({ et }), et toutes les instructions d'un programme en C se trouvent à l’intérieur d'une fonction. Dans un premier temps, nos programmes seront uniquement constitués de cette seule fonction, il est donc très important de ne rien écrire en dehors des accolades. De plus, un programme en C doit toujours se terminer par une ligne vide, faites donc toujours l'effort d’en ajouter une après l'accolade fermante.

Notre fonction main contient le mot « void » entre parenthèses, ce qui signifie que l’on ne donne aucun paramètre à la fonction main, il est en effet possible de le faire mais ce n’est pas de notre niveau.

Les instructions[modifier | modifier le wikicode]

À l’intérieur de notre fonction main, on retrouve deux instructions, ce sont des ordres donnés à l’ordinateur pour exécuter une tâche précise. Dans le cas présent, ces instructions sont les suivantes :

printf("Hello world!\n");
return 0;

La première de nos deux instructions est celle-ci :

printf("Hello world!\n");

Cette instruction appelle une fonction qui permet d'afficher le message entre guillemets à l'écran, dans notre cas, elle affiche donc le message « Hello world! ». Le symbole « \n » placé à la fin permet de demander à la fonction de faire un retour à la ligne. Cette instruction se termine par un point-virgule, c’est le cas de toutes les instructions en C (il existe néanmoins certaines exceptions que nous aurons l’occasion de voir des les chapitres suivants), l'oubli d'un point-virgule à la fin d'une instruction ferra systématiquement échouer la compilation. Ne pas mettre de point-virgule est une erreur courante chez les débutants en C, soyez donc particulièrement vigilant la dessus.

Revenons un instant sur ce qui a été dit plus haut : « cette instruction appelle une fonction », pourtant, il avait été stipulé précédemment que le programme était uniquement constitué de la fonction main. En fait, printf est une fonction toute prête, inclue et utilisable grâce aux directives de préprocesseur dont je vous ai parlé. La fonction principale main fait donc appel à la fonction printf afin d'afficher un message à l'écran. C’est comme ça que chaque programme C est conçu : main appelle des fonctions qui à leur tour vont appeler d’autres fonctions, et ainsi de suite.

La deuxième instruction est la suivante :

return 0;

Cette instruction permet, comme son nom l'indique, de retourner une valeur. C'est cette même instruction qui clôt une grande majorité de fonctions en C. Dans notre cas elle retourne 0, donc si la valeur 0 est renvoyée à la fin de l'exécution du programme, cela signifie que celui-ci a fonctionné. Par convention, les programmeurs utilisent la valeur 0 pour signifier que tout a fonctionné, et une autre valeur pour indiquer une erreur.

Notions fondamentales[modifier | modifier le wikicode]

Vous êtes désormais capable d'écrire et de comprendre un programme minimaliste en C, néanmoins il est important de maîtriser les différentes notions essentielles en programmation. Les notions suivantes ne s'appliquent pas uniquement au C, elles sont communes à de nombreux autres langages de programmation. Vous ne devriez pas rencontrer de réelle difficulté dans cette partie, mais il est important de bien assimiler les notions qui vont suivre.

Les mots-clés[modifier | modifier le wikicode]

Les mots-clés sont des mots spéciaux, réservés par le compilateur, que l’on ne peut pas utiliser à notre guise. Ils permettent entre autres la déclaration de fonctions, le renvois de valeurs, etc. 32 mots-clés sont réservés par le langage C, ceux-ci sont répertoriés dans la liste suivante (voir la norme C89 - A.1.1.2 Keywords) :

auto double int struct
break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while

Nous aurons l’occasion d'étudier leur utilité en temps voulu tout au long de ce cours. Vous remarquerez que ces mots-clés sont automatiquement colorés par votre IDE ou votre traitement de texte si celui-ci gère la coloration syntaxique.

Les opérateurs[modifier | modifier le wikicode]

Les opérateurs sont des symboles qui constituent la base des expressions (nous verrons plus bas de quoi il s’agit). Ils permettent par exemple de faire des opérations comme l’addition ou la multiplication, de comparer de deux valeurs, de modifier une valeur, etc. De même qu’en mathématiques, certains opérateurs sont prioritaires par rapport à d'autres.

Les opérateurs en C sont répertoriés dans la liste suivante (voir la norme C89 — A.1.1.6 Operators) :

[ ] ( ) . ->
++ -- & * + - ~ ! sizeof
/ % << >> < > <= >= == != ^ | && ||
? :
= *= /= %= += -= <<= >>= &= ^= |=
, # ##

Vous noterez que sizeof est à la fois un mot-clé et un opérateur.

En C, les opérateurs peuvent être classés parmi sept catégories :

  1. les opérateurs arithmétiques
  2. les opérateurs d’affectation
  3. les opérateurs logiques
  4. les opérateurs de comparaison
  5. l’opérateur conditionnel
  6. les opérateurs bit-à-bit
  7. les quelques opérateurs inclassables

Tout comme les mots-clés, nous aurons l’occasion d'examiner ces opérateur en tant voulu tout au long de ce cours.

Instructions et expressions[modifier | modifier le wikicode]

Une instruction est un ordre qui permet d’exécuter telle ou telle action. Les instructions peuvent être comparées à une phrase verbale en français. Voici quelques exemples d'instructions pour bien comprendre :

Instruction en C Traduction en français
printf("Hello world!");
Affiche le message « Hello world! ».
return 2 + 5;
Renvoie la valeur 2 + 5.

Comme dis plus haut dans le chapitre, les instructions doivent toujours se terminer par un point-virgule, à quelques exceptions près sur lesquelles nous reviendrons plus tard dans le cours.


Une expression quant à elle est évaluée et produit un résultat. Si l’on reprend la comparaison précédente, une expression serait le complément d'objet direct dans une phrase verbale. Voici quelques exemples d'expressions en C pour bien comprendre :

Expression en C Place de l’expression dans une phrase
"Hello world!"
COD dans la phrase « Affiche le message "Hello world!". »
2 + 5
COD dans la phrase « Renvoie la valeur 2 + 5. »

Généralement, une expression ne peut être écrite seule, elle doit être introduite par une instruction.


La différence entre les deux notions d'instruction et d'expression est un peu subtile et conduit parfois à des confusions, afin d’être sûr que vous les avez bien assimilés, voici un dernier exemple reprenant les deux notions :

x = 2 + 3;

Il s'agit bien d'une instruction puisqu'on donne un ordre à l’ordinateur (« Affecte la valeur 2 + 3 à x »), mais on y retrouve aussi une expression qui produit la valeur 5 comme résultat. Vous verrez qu’en C, la majorité des lignes de code sont des instructions contenant des expressions. C’est ce qui s’appelle la programmation impérative. C’est le choix des concepteurs du langage, mais ce n’est pas le seul « type » de programmation, il en existe bien d'autres qui ne nous concernent pas directement en tant qu’utilisateurs du C.

Les blocs d’instructions[modifier | modifier le wikicode]

Un bloc d’instructions est formé d’une suite d’instructions délimitée par des accolades, et tout ce qu’il y a entre les accolades est par conséquent à l’intérieur d’un bloc d’instructions. La fonction main écrite précédemment est par exemple suivie d’un bloc d’instructions composé de deux instructions.

Bien présenter son code[modifier | modifier le wikicode]

Afin que votre code soit clair et agréable à relire, il est important de respecter les quelques règles de présentation suivantes :

Espacer son code[modifier | modifier le wikicode]

Lorsque l’on écrit un texte en français, on laisse de l'espace entre deux paragraphes afin de faciliter la lecture, il en va de même pour la programmation. On insère donc des retours à la ligne dans un code source pour le rendre plus clair et plus lisible. Par exemple, les deux codes ci-dessous sont identiques pour le compilateur, mais le second est plus lisible pour le programmeur que le premier.

#include <stdio.h>
int main(void)
{ printf("Hello world!\n");
printf("How are you?\n");
return 7-(3+4);}
#include <stdio.h>

int main (void)
{
printf("Hello world!\n");
printf("How are you?\n");

return 7-(3+4);
}

Si l'ajout d'espace permet de gagner en lisibilité, cela est rarement suffisant, et il est important d'indenter son code. L’indentation permet de faire ressortir des blocs de code par l’ajout de tabulations ou d’espaces dans un code source. Un code bien indenté est un code clair et agréable à lire. Il existe de nombreux styles d’indentation différents. C'est à vous de choisir celui que vous préférez, et de vous y tenir. Ce cours utilisera quant à lui le style Allman (ou style ANSI).

Pour bien illustrer cela, voici le code précédent, puis ce même code espacé et indenté :

#include <stdio.h>
int main(void)
{ printf("Hello world!\n");
printf("How are you?\n");
return 7-(3+4);}
#include <stdio.h>

int main(void)
{
    printf("Hello world!\n");
    printf("How are you?\n");

    return 7 - (3 + 4);
}

Il faut aussi que vous sachiez qu’il existe une règle qui limite le nombre de caractères par ligne à 80. C'est néanmoins un principe très ancien et vous n’êtes pas du tout obligé de l'adopter, ce ne seras d'ailleurs pas le cas dans ce cours. Mais sachez que certains l’utilisent encore, et ne soyez pas surpris si certains codes suivent cette règle.

Commenter son code[modifier | modifier le wikicode]

Il est nécessaire de commenter son code source pour décrire les passages un peu complexes ou pour offrir des repères dans certaines parties de code. Un commentaire est ignoré par le compilateur : c’est un message utile uniquement au développeur pour la relecture de son programme. Il est primordial de commenter son code source tout au long de son écriture, cela permet de mieux se retrouver dans un programme un peu long, ou de reprendre sans difficulté l'écriture d'un programme laissé de côté quelques temps.

Un commentaire en C est écrit entre les signes /* et */ :

/* Ceci est un commentaire */

Un commentaire peut très bien s'étendre sur plusieurs lignes :

/* Ceci est un commentaire qui
   prend plusieurs lignes. */

Si les commentaires sont important, en mettre trop risque de rendre le code encore plus compliqué à comprendre. Il faut donc trouver un juste milieu, c'est-à-dire commenter les points importants du programme sans pour autant commenter chaque ligne. De nombreuses instructions sont évidentes, et les commenter serais superflu. Par ailleurs, il est conseiller d'expliquer l'utilité d'une suite d'instruction de manière générale plutôt que de commenter chaque ligne une à une.

L’idée de base est que les commentaires doivent guider la compréhension d'un code source et non pas être une simple reformulation de chaque ligne.

Voilà à quoi ressemblerait notre code minimaliste (excessivement) commenté :

/* Directive de préprocesseur qui permet de charger des fonctions utiles */
#include <stdio.h>

/* La fonction principale, le cœur du programme */
int main(void)
{
    /* Et des instructions,
       elles se terminent par un point-virgule */
    printf("Hello world!\n");

    return 0;
}

/* Fin du code, le programme s’achève ici, après une ligne vide */