Un programme simple comprend:
main
, unique et obligatoire qui est le point d’entrée du programme (i.e. quel que soit le programme, l’exécution commence forcément à la fonction main
).En C
, un exemple de programme simple:
En C
, main
est une fonction qui fournit un code de retour:
int
(entier)echo $?
Voici un exemple de programme simple:
Sur ce programme, un certain nombre de choses sont importantes:
main
: voir précédemment, il est obligatoireN
est définie avant le main
printf
qui permet d’écrire à l’écran. Cependant ça n’est pas une fonction de base de C
et doit par conséquent sa définition doit être incluse pour que le compilateur puisse compiler le programme. L’inclusion se fait via #include <stdio.h>
, stdio.h
(standard input-output) étant un fichier qui centralise les fonctions / types / variables utiles pour récupérer des données au clavier et afficher à l’écran. La fonction printf
est détaillée dans la section suivante.printf
et scanf
sont deux fonctions que vous utiliserez énormément. La première permet d’afficher messages et données à l’écran tandis que la deuxième permet de demander des informations à l’utilisateur (et donc de récupérer ce qui est entré au clavier).
printf
La syntaxe générale de printf
est un peu complexe et donc nous ne la détaillerons pas tout de suite. Son utilisation sur un programme simple est la suivante:
Ce programme est compilé puis exécuté:
Les %d
, %c
, %f
… sont des chaînes de formatage et permettent d’afficher les valeurs de vos variables, elles commencent nécessairement par le caractère %
. La liste complète des chaînes de formatage se trouve ci-dessous:
Il est également possible de modifier la mise en forme de l’affichage avec un certain nombre de modificateurs et la syntaxe générale devient: %(fl)(ent)(.)(pre)(long)type
où type est l’une des valeurs indiquées précédemment (d
, i
, u
…). Les modificateurs sont indiqués entre parenthèses car ils sont optionnels.
fl
: permet de modifier l’alignement: -
impose une justification à gauche; +
ajout un signe +
pour les nombres positifs, un espace pour les nombres sans signe; 0
permet d’ajouter des 0 en préfixe; #
active la forme secondaire pour l’affichage (préfixe sur les formes octales et hexadécimales…)ent
est un entier qui indique en caractères la taille minimum du formatagepre
est un entier qui indique la précision (i.e. le nombre de chiffres après la virgule)long
est un modificateur de longueur, vaut soit h
(pour les types short
) ou l
(pour les types long
ou double
).Voici quelques exemples:
Programme que l’on compile puis que l’on exécute.
scanf
La syntaxe est proche de printf
puisqu’elle utilise également les chaînes de formatage. Ci-dessous, un programme qui illustre son utilisation:
Ce programme est compilé puis exécuté:
Plusieurs choses importantes sont à retenir:
En général, le compilateur vous indique qu’il y a une erreur possible via un warning
. Dans l’exemple précédent, en supprimant le &
devant le f
de l’appel à scanf
, le compilateur affiche le message suivant:
Par exemple, si l’utilisateur utilise la virgule ,
comme séparateur alors le programme ne fonctionne pas comme attendu:
Soit le programme suivant qui demande 3 caractères à l’utilisateur:
que l’on compile puis exécute:
On constate que le programme ne fonctionne pas correctement: la demande du deuxième caractère est zappée (même si le message du printf
est affiché à l’écran) et du coup on ne peut rentrer que deux valeurs. Ceci s’explique par le fait que le retour à la ligne \n
est un caractère (code ASCII
égal à 10) et il est par conséquent scanné par le deuxième appel de scanf
ce qui est confirmé par le fait que dans le terminal on voit y =
puis un retour à la ligne. Par conséquent il faut être particulièrement vigilant lorsque l’on scanne des caractères. Une solution (pas très élégante) est de modifier les deux derniers appels à scanf
en ajoutant un retour à la ligne (i.e. scanf("\n%c", &y);
).
Ce problème est présent uniquement lorsque l’on scanne des caractères. Les espaces et retours à la ligne sont automatiquement supprimés par scanf
lorsque l’on scanne des données d’autres types.
Les redirections sont des moyens simples de rediriger des données depuis/vers des fichiers. Les 3 entrées/sorties standard sont:
stdin
(0
): entrée standard qui correspond à ce qui est tapé au clavierstdout
(1
): sortie standard qui correspond à ce qui est affiché à l’écranstderr
(2
): erreur standard qui affiche les message d’erreurs (par défaut à l’écran)La syntaxe générale d’une redirection est la suivante: supposons l’existence de commande
qui est une commande système ou un programme.
commande < fichier
permet de rediriger l’entrée standard. Ceci signifie que les valeurs que tape habituellement l’utilisateur au clavier seront directement lues dans fichier
.commande > fichier
permet de rediriger la sortie standard. Tous les messages habituellement affichés à l’écran seront écrits dans fichier
. Attention: si fichier existait déjà, son contenu est écrasé.commande >> fichier
permet de rediriger la sortie standard. Tous les messages habituellement affichés à l’écran seront écrits dans fichier
. Attention: si fichier existait déjà, les messages de commande
sont ajoutés à la fin du fichier.commande 2> fichier
permet de rediriger l’erreur standard, son fonctionnement est le même que pour la sortie standard.Bien entendu ces commandes peuvent être combinées. Reprenons le programme de la section précédente. Soit fichier1
qui contient 9 z 3.14156
, il est possible de faire:
On remarque que l’exécution de notre programme avec les redirections n’affiche absolument rien à l’écran. On peut regarder le contenu de fichier2
pour vérifier que la redirection a bien fonctionné:
Les entrées-sorties ne sont pas immédiates mais sont stockées dans un tampon (buffer). En effet les opérations qui envoient des données depuis / vers un périphérique vers / depuis la mémoire de l’ordinateur sont très coûteuses en temps de calcul. Par conséquent, les instructions du style printf
et scanf
sont exécutées et leurs résultats sont stockés dans le tampon jusqu’à ce que celui soit plein. Une fois plein, le tampon est vidé vers l’écran (dans le cas d’un printf
) ou depuis le clavier (dans le cas d’un scanf
). Ceci permet de minimiser les échanges entre mémoires et périphériques.
Un moyen simple de constater la présence de tampons est de compiler et d’exécuter le programme ci-dessus dont le principe est très simple. On souhaite afficher un point '.'
à l’écran toutes les secondes. Pourtant à l’exécution on constate que le programme ne fonctionne pas de manière attendue: rien n’est affiché à l’écran pendant 10 secondes puis les 10 '.'
sont affichés d’une traite. Ceci s’explique par le fait que les caractères sont stockés dans le tampon et comme il n’est pas plein, il n’est pas transféré à l’écran. Quand le programme se termine, tous les tampons sont vidés et donc l’affichage à l’écran est effectué. Il est possible de forcer le vidage des tampons d’entrées-sorties avec la fonction fflush
. Par exemple fflush(stdout)
permet de vider le tampon de la sortie standard et fflush(stdin)
permet de vider le tampon de l’entrée standard.