Cours C Avancée Révision 1
Cours C Avancée Révision 1
Cours C Avancée Révision 1
Avancée
avencée
octobre 2022
Langages de programmation
Un ordinateur est une machine bête, ne sachant qu'obéir, et à très peu de choses :
* addition, soustraction, multiplication en binaire, uniquement sur des entiers,
* sortir un résultat ou lire une valeur binaire (dans une mémoire par exemple),
* comparer des nombres.
Sa puissance vient du fait qu'il peut être PROGRAMME, c'est à dire que l'on peut lui donner, à
l'avance, la séquence (la suite ordonnée) des ordres à effectuer l'un après l'autre. Le grand avantage de
l'ordinateur est sa rapidité. Par contre, c'est le programmeur qui doit TOUT faire. L'ordinateur ne
comprenant que des ordres codés en binaire (le langage machine), des langages dits "évolués" ont été
mis au point pour faciliter la programmation, au début des années 60. Puis, pour des besoins
pédagogiques principalement, ont été créés le BASIC, pour une approche simple de la programmation,
et PASCAL au début des années 70.
Ce dernier (comme le C) favorise une approche méthodique et disciplinée (on dit "structurée"). Le C a
été développé conjointement au système d'exploitation UNIX, dans les Laboratoires BELL, par Brian
W Kernigham et Dennis M Ritchie, qui ont défini en 78, dans "The C Language", les règles de base de
ce langage. Le but principal était de combiner une approche structurée (et donc une programmation
facile) avec des possibilités proches de celles de l'assembleur, tout en restant standard (c'est à dire
pouvoir être implanté sur n'importe quelle machine). Puis ce langage a été normalisé en 88 (norme
ANSI), cette norme apportant un nombre non négligeable de modifications au langage.
Le C est un langage compilé, c'est à dire qu'il faut :
* entrer un texte dans l'ordinateur (à l'aide d'un programme appelé EDITEUR),
* le traduire en langage machine (c'est à dire en codes binaires compréhensibles par l'ordinateur) : c'est
la compilation et, si plusieurs modules ont été compilés séparément, l'édition de liens (LINK ou
BIND), Contrairement à un basic interprété, l'exécution sera beaucoup plus rapide puisqu'il n'y a plus
de traduction à effectuer, mais la phase de mise au point sera plus complexe.
Bien que le langage soit normalisé, un certain nombre de points dépendent de la machine et du
compilateur utilisé. Je vous conseille TURBO C, le plus pratique d'emploi (en particulier parce qu'il
possède son propre éditeur de texte).
Connaissances de base
Regardons ce petit programme :
Type de données
Exemple
Fonctions d'entrées/sorties les plus utilisées
Exemple
Exemple
Exemple
putch(char) : affiche sur l'écran (ou du moins stdout) le caractère fourni en argument (entre
parenthèses).
stdout est l'écran, ou un fichier si on a redirigé l'écran (en rajoutant >nomfichier derrière l'appel du
programme, sous DOS ou UNIX). Si besoin est, cette fonction rend le caractère affiché ou EOF en cas
d'erreur.
getch(void) : attend le prochain appui sur le clavier, et rend le caractère qui a été saisi. L'appui sur une
touche se fait sans écho, c'est à dire que rien n'est affiché à l'écran. En cas de redirection du clavier, on
prend le prochain caractère dans le fichier d'entrée.
getche(void) : idem getch mais avec écho. On pourrait réécrire cette fonction en fonction des deux
précédentes :
char getche(void);
{
char caractere;
caractere=getch();
putch(caractere);
return(caractere);
}
ou même {return(putch(getch))}
Dans la pratique, ce n'est pas ainsi que getche est réellement défini, mais en assembleur pour un
résultat plus rapide.
Dans STDIO.H, on trouve des fonctions plus évoluées, pouvant traiter plusieurs caractères à la suite
(par les fonctions de conio.h), et les transformer pour en faire une chaîne de caractères ou une valeur
numérique, entière ou réelle par exemple. Les entrées sont dites "bufférisées", c'est à dire que le texte
n'est pas transmis,et peut donc encore être modifié, avant le retour chariot.
puts(chaîne) affiche, sur stdout, la chaîne de caractères puis positionne le curseur en début de ligne
suivante. puts retourne EOF en cas d'erreur.
gets(chaîne) lecture d'une chaîne sur stdin. Tous les caractères peuvent être entrés, y compris les
blancs. La saisie est terminée par un retour chariot. Gets retourne un pointeur sur le premier caractère
entré (donc égal à son paramètre d'entrée, ou le pointeur NULL en cas d'erreur (fin du fichier stdin par
exemple).
printf(format,listevaleurs) affiche la liste de valeurs (variables ou expressions) dans le format choisi.
Le format est une chaîne de caractères entre guillemets (doubles quote "), dans laquelle se trouve un
texte qui sera écrit tel quel, des spécifications de format (débutant par %) qui seront remplacées par la
valeur effective des variables, dans l'ordre donné dans listevaleurs, et de caractères spéciaux (\). Printf
retourne le nombre de caractères écrits, ou EOF en cas de problème.
Une spécification de format est de la forme :
% [flag][largeur][.précision][modificateur]type (entre [] facultatifs)
Le flag peut valoir : − (cadrage à gauche, rajout de blancs si nécessaire à droite), + (impression du
signe, même pour les positifs), blanc (impression d'un blanc devant un nombre positif, à la place du
signe), 0 (la justification d'un nombre se ferra par rajout de 0 à gauche au lieu de blancs). D'autres
Flags sont possibles mais moins utiles, pour plus de détails voir l'aide en ligne de Turbo C.
La largeur est le nombre minimal de caractères à écrire (des blancs sont rajoutés si nécessaire). Si le
texte à écrire est plus long, il est néanmoins écrit en totalité. En donnant le signe * comme largeur, le
prochain argument de la liste de valeurs donnera la largeur (ex printf("%*f",largeur,réel)).
La précision définit, pour les réels, le nombre de chiffres après la virgule (doit être inférieur à la
largeur).
Dans le cas d'entiers, indique le nombre minimal de chiffes désiré (ajout de 0 sinon), alors que pour
une chaîne (%s), elle indique la longueur maximale imprimée (tronqué si trop long). La précision peut,
comme la largeur, être variable en donnant.*
Le modificateur peut être : h (short, pour les entiers), l (long pour les entiers, double pour les réels), L
(long double pour les réels).
Le type est : c (char), s (chaîne de caractères, jusqu'au \0), d (int), u (entier non signé), x ou X (entier
affiché en hexadécimal), o (entier affiché en octal), f (réel en virgule fixe), e ou E (réel en notation
exponentielle), g ou G (réel en f si possible, e sinon), p (pointeur), % (pour afficher le signe %).
Les caractères spéciaux utilisables dans le format sont \t (tabulation), \n (retour à la ligne), \\ (signe \),
\nb tout code ASCII, en décimal, hexa ou octal (\32=\040=\0x20=' ').
scanf(format,listeadresse) lecture au clavier de valeurs, dans le format spécifié. Les arguments sont
des pointeurs sur les variables résultats (dans le cas de variables scalaires, les précéder par l'opérateur
&). Scanf retourne le nombre de valeurs effectivement lues et mémorisées (pas les %*).
Le format peut contenir (entre ") : du texte (il devra être tapé exactement ainsi par l'utilisateur, et ne
sera pas stocké), des séparateurs blancs (l'utilisateur devra taper un ou plusieurs blancs, tabulations,
retours à la ligne),et des spécifications de format, sous la forme %[*][largeur][modificateur] type.
* signifie que la valeur sera lue mais ne sera pas stockée (ex scanf("%d%*c%d",&i,&j) : lecture de
deux entiers séparés par n'importe quel caractère)
La largeur est la largeur maximale lue, scanf s'arrête avant s'il trouve un séparateur (blanc, tab, CR).
les modificateurs et types sont les mêmes que pour printf (excepté d,o,x : pour entiers short, D,O,X
pour long). Dans le cas des chaînes (%s), le blanc est également un séparateur. On ne pourra donc pas
entrer une chaîne avec des blancs par scanf, il faut utiliser gets.
Scanf lit dans stdin en considérant les retours chariot (CR) comme des blancs. on peut donc séparer
par des CR plusieurs valeurs demandées dans le même scanf. Mais de même, si scanf a pu lire tous ses
arguments sans arriver à la fin de la ligne, la suite servira au prochain scanf. Utilisez gets(bidon) avant
(pour être sur de commencer sur une nouvelle ligne) ou après scanf (pour ignorer la fin de la ligne) si
nécessaire.
getchar(void) fonctionne comme getche, mais utilise le même tampon que scanf.
On dispose aussi de sprintf(chaîne, format, listevaleurs) qui permet d'écrire dans une chaîne plutôt
que sur l'écran, et donc faire des conversions numériques −>ASCII; et de sscanf(chaîne, format,l
isteadresse) qui lit dans une chaîne plutôt qu'au clavier. On possède encore d'autres fonctions dans
STDIO, en particulier pour gérer les fichiers.