II. Premiers pas▲
II-A. Système d'exploitation et C▲
Pour pouvoir réaliser des programmes en C, il est nécessaire de s'appuyer sur un système d'exploitation. Le système d'exploitation utilisé est ici Gnu/Linux. Néanmoins, la quasi-totalité de ce qui est décrit ici peut être réalisé en utilisant d'autres systèmes d'exploitation.
Cet ouvrage n'est pas une introduction à l'utilisation de Gnu/Linux. Nous n'évoquerons donc que les outils nécessaires à la programmation en C.
II-B. Utiliser un éditeur sous Gnu/LinuxUtiliser un éditeur sous Gnu/Linux▲
Nous allons dans cette section tenter de définir une manipulation pour lancer un éditeur(3). Il existe une multitude d'éditeurs de texte qui permettent de saisir des programmes : Emacs (que j'utilise en ce moment même), Kate, Bluefish, Gedit…
Souvent, les éditeurs sont accessibles quelque part dans un menu. En ce qui nous concerne, nous allons lancer l'éditeur de texte depuis la ligne de commande du shell. Pour cela, nous allons exécuter un terminal. Selon la distribution que vous utilisez le terminal n'est pas forcément rangé au même endroit. Voici quelques pistes qui pourront vous aider :
- sous Ubuntu, faites Applications / Accessoires / Terminal ;
- sous Xfce (et avec une Debian), faites clic droit, puis Terminal ;
- dans un autre environnement, recherchez quelque chose qui pourrait s'appeler Terminal, Console ou Xterm.
Dans cette nouvelle fenêtre qui ressemble à celle de la figure 1.1, exécutez l'éditeur Scite en tapant la commande scite puis en validant. L'éditeur doit s'ouvrir (voir figure 1.2).
Scite est un éditeur très simple d'utilisation. Il est de plus disponible pour plusieurs systèmes d'exploitation, est léger, peut être personnalisé, offre la coloration syntaxique, permet de « plier » les fonctions…
Si en essayant de lancer la commande scite vous obtenez un message d'erreur comme : Commande inconnue ou Command not found, c'est que Scite n'est probablement pas installé sur votre machine. Vous devrez alors regarder du côté des outils de gestion des paquetages pour ajouter ce logiciel (peut être disposez-vous des outils de gestion des paquetages : Synaptic, Aptitude, Rpmdrake, Gurpmi, Yast …).
II-C. Exemple de programme▲
Voici un premier programme. Il est fonctionnel, même s'il n'est pas normalisé(4). Il affiche le mot Bonjour à l'écran. À l'aide de votre éditeur de texte (dans la fenêtre Scite donc), tapez le texte qui se trouve à l'intérieur du cadre suivant :
main (
) {
puts (
"
Bonjour
"
);
getchar (
);
}
Puis, sauvegardez ce fichier (raccourci clavier : CTRL+S) sous le nom suivant : programme1.c
Une fois le texte du programme tapé, il faut le compiler, c'est-à-dire le transformer en programme exécutable (nous reviendrons sur la compilation plus tard). Nous allons donc ouvrir une seconde fenêtre dans laquelle nous allons compiler notre programme : comme tout à l'heure lancez un terminal (figure 1.1).
La compilation se fait avec le compilateur gcc. Tapez dans cette nouvelle fenêtre(5) :
gcc -o programme1 programme1.c
De la même façon que vous pourriez ne pas disposer de l'éditeur Scite, il se peut que vous n'ayez pas les outils de développement. Là aussi, selon votre distribution, recherchez l'outil de gestion des logiciels installés, et installez le compilateur Gcc. Il est probable que son installation induise l'installation d'autres outils de développement nécessaires (la plupart des outils d'installation de paquets gèrent les dépendances entre logiciels).
Si vous n'avez pas fait d'erreur, la ligne précédente ne provoquera aucun affichage (pas de nouvelle, bonne nouvelle…). La commande entrée vient de créer un fichier nommé programme1. Vous pouvez le vérifier en tapant ls -l (attention, tapez bien ls-l) qui devrait vous renvoyer quelque chose du type :
-rw-r--r-- 1 dschang dschang 44 2008-10-14 11:10 programme1.c
-rwxr-xr-x 1 dschang dschang 6525 2008-10-14 11:11 programme1
En y regardant de plus près, nous pouvons voir le fichier intitulé programme1.c qui a été sauvegardé à 11h10 et qui contient 44 octets. En dessous se trouve le fichier programme1 qui vient d'être créé et qui contient 6525 octets. Ce dernier fichier contient le code machine (code qui est compréhensible par la machine).
Le fichier programme1 est un « fichier exécutable ». Le fichier programme1.cest un « fichier source » (source de tous les bonheurs de Gnu/Linux…). Un fichier source désigne un fichier qu'un être humain peut comprendre par opposition à un exécutable que seule la machine arrive à comprendre. Il ne reste plus qu'à exécuter le programme :
./programme1
La machine affichera alors Bonjour et attendra que vous appuyiez sur ENTREE.
Nous reviendrons par la suite sur le fait qu'il faille taper ./programme1 et pas simplement programme1.
Par ailleurs, vous avez pu constater que la fin des lignes se terminait par un ; sauf la première ligne (celle qui contient le mot main). Nous reviendrons là-dessus… Disons pour l'instant que c'est un peu comme en français où chaque phrase se termine par un « . » sauf le titre.
II-D. Normalisation du programme▲
Jusqu'à présent, nous avons fait un peu « dans le sale ». Nous nous en rendrons compte en demandant au compilateur d'être plus bavard. Lancez la commande :
gcc -o programme1 programme1.c -Wall
Observez les insultes :
programme1.c:5: warning: return-type defaults to `int'
programme1.c: In function `main':
programme1.c:6: warning: implicit declaration of function `puts'
programme1.c:9: warning: control reaches end of non-void function
Les remarques du compilateur vous paraissent peut-être peu compréhensibles (voire offensantes) et c'est normal.
L'option de compilation -Wall permet de « déclencher la production de messages soulignant toute technique autorisée mais discutable », en deux mots : à éviter.
Nous allons donc normaliser ce programme.
Fondamentalement, le langage C n'est qu'un nombre restreint d'instructions et un ensemble de bibliothèques. Dans ces dernières, le compilateur trouve les fonctions et les applications qui lui permettent de créer un programme exécutable. C'est un peu ce que vous faites lorsque vous recherchez dans une encyclopédie pour réaliser un exposé.
Certaines bibliothèques (les plus courantes) sont incluses par défaut ce qui permet à notre programme de se compiler(6).
La fonction puts est stockée dans la bibliothèque standard d'entrées-sorties, incluse par défaut. Néanmoins, l'utilisation d'une bibliothèque nécessite que nous informions le compilateur de notre souhait de l'utiliser : il suffit d'ajouter #include <fichier en-tête bibliothèque> en début de programme(7).
Ainsi, puisque nous utilisons la fonction puts, qui est dans la librairie standard d'entrées/sorties, nous indiquerons en début de programme(8) : #include <stdio.h>
Un autre point à corriger est l'ajout de la ligne return 0. Tout programme doit renvoyer une valeur de retour, tout à la fin. Cette valeur de retour permet de savoir si le programme que l'on exécute s'est correctement terminé. En général 0 signifie une terminaison sans erreur. Enfin, il faut transformer la ligne main() en int main(). Ce point sera détaillé par la suite lorsque nous parlerons des fonctions…
En rajoutant ces quelques correctifs nous obtenons donc :
#include <stdio.h>
int
main (
) {
puts (
"
Bonjour
"
);
getchar (
); /* Permet d'attendre la frappe d'une touche */
return
0
;
}
II-E. Petit mot sur ce qu'est une bibliothèque▲
À l'instar de l'étudiant qui recherche dans des livres, nous pouvons dire que le « .h » représente l'index du livre et le « .c » le contenu du chapitre concerné.
Après avoir lu (et retenu) le contenu des fichiers .h inclus, si le compilateur rencontre l'appel à la fonction puts, il est en mesure de vérifier si la fonction figurait dans un des include. Si ce n'est pas le cas, il émettra un avertissement.
II-F. Un exemple de fichier en-tête▲
Vous trouverez ci-dessous, un extrait du fichier en-tête stdio.h. On y retrouve notamment la déclaration de puts (en dernière ligne de l'extrait) que nous venons de mentionner et la déclaration de printf que nous verrons dans les chapitres suivants. C'est assez compliqué… on y jette juste un œil, pas plus ;)
/* Write formatted output to STREAM. */
extern
int
fprintf __P ((
FILE *
__restrict __stream,
__const char
*
__restrict __format, ...));
/* Write formatted output to stdout. */
extern
int
printf __P ((
__const char
*
__restrict __format, ...));
/* Write formatted output to S. */
extern
int
sprintf __P ((
char
*
__restrict __s,
__const char
*
__restrict __format, ...));
/* Write formatted output to S from argument list ARG. */
extern
int
vfprintf __P ((
FILE *
__restrict __s,
__const char
*
__restrict __format,
_G_va_list __arg));
/* Write formatted output to stdout from argument list ARG. */
extern
int
vprintf __P ((
__const char
*
__restrict __format,
_G_va_list __arg));
/* Write formatted output to S from argument list ARG. */
extern
int
vsprintf __P ((
char
*
__restrict __s,
__const char
*
__restrict __format,
_G_va_list __arg));
/* Write a string, followed by a newline, to stdout. */
extern
int
puts __P ((
__const char
*
__s));
II-G. Compléments▲
Explicitons notre programme,
#include <stdio.h>
int
main (
) {
puts (
"
Bonjour
"
);
getchar (
); /* Permet d'attendre la frappe d'une touche */
return
0
;
}
- puts: permet d'afficher du texte suivi d'un retour à la ligne.
- getchar: permet d'attendre la frappe d'une touche suivie d'une validation par la touche ENTREE, ou un simple appui sur la touche ENTREE.
- /* Commentaire */: met en commentaire tout le texte compris entre /* et */(9). On trouvera aussi// qui permet de mettre le reste de la ligne courante en commentaire(10).
Notre programme affiche donc Bonjour et attend que l'on appuie sur la touche entrée ou sur une autre touche puis la touche entrée.
II-H. Squelette de programme▲
On peut définir le squelette d'un programme C de la façon suivante :
/* Déclaration des fichiers d'entêtes de bibliothèques */
int
main (
) {
/* Déclaration des variables (cf. chapitres suivants...) */
/* Corps du programme */
getchar
(
); /* Facultatif mais permet d'attendre l'appui d'une touche */
return
0
; /* Aucune erreur renvoyée */
}
II-I. Blocs▲
La partie de programme située entre deux accolades est appelée un bloc. On conseille de prendre l'habitude de faire une tabulation(11) après l'accolade. Puis retirer cette tabulation au niveau de l'accolade fermante du bloc. Ainsi, on obtient :
int
main (
) {
Tabulation
Tout le code est frappé à cette hauteur
}
Retrait de la tabulation
Tout le texte est maintenant frappé à cette hauteur.
Cette méthode permet de contrôler visuellement la fermeture des accolades et leurs correspondances(12).
II-J. Commentaires▲
Bien commenter un programme signifie qu'une personne ne connaissant pas votre code doit pouvoir le lire et le comprendre. Les commentaires sont indispensables dans tout bon programme. Ils peuvent être placés à n'importe quel endroit. Ils commencent par /* et se terminent par */ :
/* Commentaire */
Comme nous l'avons déjà mentionné, vous trouverez aussi parfois des commentaires C++ :
// Le reste de la ligne est un commentaire
II-K. Exercice d'application▲
Écrivez un programme qui :
- affiche « Salut toi, appuie sur une touche s'il te plaît » ;
- attend l'appui d'une touche ;
- affiche : « Merci d'avoir appuyé sur une touche ».
Une fois que vous serez satisfait de votre solution, vous pourrez la comparer avec la solution qui apparaît un peu plus loin.
Sous Linux, il est possible d'éviter de retaper à chaque fois les commandes :
Pour cela, il suffit d'appuyer plusieurs fois sur la flèche vers le haut , ce qui fera réapparaître les dernières commandes validées. Les flèches haut et bas permettent ainsi de circuler dans l'historique des commandes entrées.
II-L. Corrigé de l'exercice du chapitre▲
#include <stdio.h>
int
main (
) {
/* Affiche premier message */
puts (
"
Salut toi, appuie sur une touche s'il te plaît
"
);
getchar (
); /* Attend la frappe d'une touche */
/* Affiche le second message */
puts (
"
Merci d'avoir appuyé sur une touche
"
);
return
0
;
}
II-M. À retenir▲
À l'issue de ce chapitre, il serait souhaitable de :
- Se souvenir que l'éditeur que l'on utilise dans cet ouvrage s'appelle Scite;
- Connaître les fonctions puts et getchar qui apparaissent dans le programme suivant :
#include <stdio.h>
int
main (
) {
puts (
"
Bonjour
"
);
getchar (
); /* Permet d'attendre la frappe d'une touche */
return
0
;
}
- Savoir compiler un code source de programme : gcc -o programme1 programme1.c
- Savoir exécuter un programme : ./programme1