Manuel complet du langage C++ pour les nuls

Chapitre 1: Introduction
1 Introduction
Ce cours présente le langage C, un langage essentiel dans l’enseignement de la programmation parce qu’il occupe une place prépondérante en informatique, qu’il possède la majorité des constructions qu’on retrouve dans les autres langages structurés modernes et que sa syntaxe a servi de base à nombre de ces langages. Ce cours est à l’informatique à peu près ce que l’algèbre et le calcul différentiel et intégral sont aux mathématiques. Les notions qu’il présente ne permettent de résoudre que des problèmes simples, mais elles sont fondamentales.
Le cours est composé d’une série d’exercices introduisant progressivement les instructions du C. Il n’est pas nécessaire de les faire tous systématiquement. En fonction de ses capacités, le lecteur peut en faire un plus ou moins grand nombre. Ces exercices sont là d’une part pour s’entraîner et pour mieux comprendre les instructions présentées, et d’autre part pour vérifier l’acquisition des connaissances.
Ce cours se termine par des mini-projets montrant à quoi sert un ordinateur dans l’industrie et la recherche: • calcul de la trajectoire d’un projectile
- rotation 3-D
- calcul d’un pont en treillis
- labyrinthe
2 Description générale de l’ordinateur
Cette section décrit très brièvement l’architecture des ordinateurs et le codage de l’information dans un ordinateur. Ces informations sont utiles pour mieux comprendre l’organisation et le fonctionnement des programmes en C.
2.1 Architecture des ordinateurs
La Figure 1 montre les éléments principaux d’un ordinateur. Celui-ci comporte essentiellement une mémoire électronique et un processeur connectés entre eux et connectés aux périphériques (le disque dur, le clavier, l’écran, etc.). La mémoire électronique est rapide. Elle contient les données (valeurs numériques, textes, dessins ) et les programmes (listes d’instructions qui font précisément l’objet de ce cours). Quand on éteint l’ordinateur, cette mémoire s’efface, à part une petite partie qui permet de relancer l’ordinateur au réenclenchement. La mémoire électronique est trop petite pour contenir tout ce qu’on veut mémoriser. C’est pourquoi l’ordinateur a à sa disposition des mémoires plus grandes mais plus lentes: le disque dur et les disquettes. Ces mémoires-là retiennent les informations quand on éteint l’ordinateur.
mémoire
FIGURE 1: La structure d’un ordinateur
Chapitre 2: Description générale de l’ordinateur
Le processeur possède une unité arithmétique et logique qui prend les instructions une à une dans la mémoire électronique et les exécute. A l’enclenchement l’ordinateur commence par exécuter des instructions à la casemémoire numéro zéro et, jusqu’à ce qu’on l’éteigne, il n’arrête pas d’en exécuter et d’en réexécuter, chargeant sa mémoire avec des programmes en provenance du disque ou créés selon vos ordres.
Tout ce qui apparaît sur l’écran lorsque vous enclenchez l’ordinateur a été dessiné par des programmes, à peu près identiques sur chaque station de travail. Ces programmes détectent également les mouvements de la souris et les touches pressées sur le clavier. Ils manipulent les informations enregistrées sur les disques et les disquettes. Ils exécutent des éditeurs de textes ou graphiques, des calculateurs. De tels programmes peuvent être développés à l’aide d’autres programmes précisément prévus pour cela. Bien évidemment le tout premier programme a dû être développé d’une autre façon, mais c’était il y a longtemps.
2.2 Le codage de l’information
Tout fonctionne en binaire dans un ordinateur, c'est-à-dire en manipulant les seules valeurs 0 et 1, représentées habituellement dans la machine par les tensions de 0 et 5V respectivement. Ces chiffres binaires, 0 et 1, à partir desquels on construit des nombres plus grands sont appelés bits, abréviation de binary digit. Toutes les données manipulables par un ordinateur sont ainsi représentées par des séquences de bits:
• Un caractère: 8 bits (code entre 0 et 255)
• Un entier: 32 bits
• Un réel en virgule flottante (32 ou 64 bits).
• sons: décomposés en échantillons
• images: décomposées en pixels.
Pour comprendre le codage de l’information, il faut connaître les puissances de 2:
27 |
26 |
25 |
24 |
23 |
22 |
21 |
20 |
128 |
64 |
32 |
16 |
8 |
4 |
2 |
1 |
Codage d’un entier de 8 bits. La figure 2 montre comment est codé un entier de 8 bits. La valeur binaire. 01100001 correspond à l’entier 97. Pour savoir cela, on aligne au dessus de chaque bit l’exposant de 2 correspondant à la position du bit, et l’on additionne toutes les puissances de 2 pour lesquelles le bit est 1. Dans notre cas, cela donne 64+32+1 = 97. Il est facile d’étendre cela à 8, 16, 32 ou 64 bits. Les nombres de 64 bits permettent de stocker des valeurs astronomiques (264 ~= 16.1018), soit 16 milliards de milliards.
position |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
puissance de 2
valeur binaire= 97 = ‘a’ = 0x61
représentation hexadécimale 0x6 0x1
FIGURE 2: Codage binaire
Codage des caractères. Les caractères sont généralement représentés sur 8 bits. Par convention, on fait correspondre certaines valeurs aux caractères de l’alphabet. La convention de codage la plus fréquente est la convention ASCII, qui fait correspondre les valeurs 97, 98, 99, aux caractères ‘a’, ‘b’, ‘c’, , et les valeurs 65, 66, 67, aux caractères ‘A’, ‘B’, ‘C’, La figure 3 résume ce codage des caractères. Notez que les caractères
4
Chapitre 2: Description générale de l’ordinateur
figurant en italique dans cette table ne sont pas affichables tels quels mais sont ce que l'on appelle des caractères de contrôle (retour à la ligne, changement de page, bip sonore, etc )
NU |
16 |
DL |
32 |
SP |
48 |
64 |
@ |
80 |
P |
96 |
‘ |
112 |
p |
||
1 |
SH |
17 |
D1 |
33 |
! |
49 |
1 |
65 |
A |
81 |
Q |
97 |
a |
113 |
q |
2 |
SX |
18 |
D2 |
34 |
" |
50 |
2 |
66 |
B |
82 |
R |
98 |
b |
114 |
r |
3 |
EX |
19 |
D3 |
35 |
# |
51 |
3 |
67 |
C |
83 |
S |
99 |
c |
115 |
s |
4 |
ET |
20 |
D4 |
36 |
$ |
52 |
4 |
68 |
D |
84 |
T |
100 |
d |
116 |
t |
5 |
EQ |
21 |
NK |
37 |
% |
53 |
5 |
69 |
E |
85 |
U |
101 |
e |
117 |
u |
6 |
AK |
22 |
SY |
38 |
& |
54 |
6 |
70 |
F |
86 |
V |
102 |
f |
118 |
v |
7 |
BL |
23 |
EB |
39 |
’ |
55 |
7 |
71 |
G |
87 |
W |
103 |
g |
119 |
w |
8 |
BS |
24 |
CN |
40 |
( |
56 |
8 |
72 |
H |
88 |
X |
104 |
h |
120 |
x |
9 |
HT |
25 |
EM |
41 |
) |
57 |
9 |
73 |
I |
89 |
Y |
105 |
i |
121 |
y |
10 |
LF |
26 |
SB |
42 |
* |
58 |
: |
74 |
J |
90 |
Z |
106 |
j |
122 |
z |
11 |
VT |
27 |
EC |
43 |
+ |
59 |
; |
75 |
K |
91 |
[ |
107 |
k |
123 |
{ |
12 |
FF |
28 |
FS |
44 |
, |
60 |
< |
76 |
L |
92 |
\ |
108 |
l |
124 |
| |
13 |
CR |
29 |
GS |
45 |
- |
61 |
= |
77 |
M |
93 |
] |
109 |
m |
125 |
} |
14 |
SO |
30 |
RS |
46 |
. |
62 |
> |
78 |
N |
94 |
^ |
110 |
n |
126 |
~ |
15 |
SI |
31 |
US |
47 |
/ |
63 |
? |
79 |
O |
95 |
_ |
111 |
o |
127 |
DT |
FIGURE 3: Codage ASCII des caractères
Notation hexadécimale. Comme la notation binaire demande énormément de chiffres pour représenter un nombre et que la notation décimale usuelle ne permet pas de manipuler les puissances de 2 facilement, on utilise souvent la notation hexadécimale, c'est-à-dire en base 16. Pour convertir un nombre noté en binaire en notation hexadécimale, il suffit de grouper les bits par blocs de 4, correspondant à des valeurs entre 0 et 15, notées 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a ( = 10), b ( = 11), c ( = 12), d ( = 13), e ( = 14), f ( = 15). On peut ainsi représenter la valeur décimale 97, dans la figure 2, par la valeur hexadécimale 0x61. Par convention et pour éviter les confusions, on fait toujours commencer les valeurs hexadécimales par les caractères 0x.
Les codages des nombres réels, des sons et des images sont un peu plus compliqués, mais se réduisent toujours à des séquences de nombres entiers manipulés par l'ordinateur sous forme de chaînes de bits.
2.3 Fonctionnement d’un processeur
Au bas niveau (niveau matériel), la seule chose qu’un microprocesseur sait faire, c’est prendre une ou deux valeurs en mémoire et les stocker temporairement dans un registre interne (un registre est une petite mémoire très rapide interne au microprocesseur), leur faire subir des opérations simples (et logique, ou logique, addition, soustraction), et remettre le résultat en mémoire. Ces trois fonctions (prendre les valeurs en mémoire, opération simples, et remettre les valeurs en mémoire) s’appellent les instructions du processeur. Toutes les opérations complexes que vous ferez avec votre ordinateur se décomposent en une séquence (parfois très longue) d’instructions.
Les microprocesseurs modernes effectuent environ 1 instruction par cycle d’horloge. Lorsque l’on sait que les microprocesseurs actuellement sur le marché fonctionnent à 500Mhz (et certains à 1Ghz), cela laisse au microprocesseur le temps d’effectuer 500 millions d’instructions par seconde.
Chaque type d’instruction a un code (par exemple 0 pour charger une valeur de la mémoire dans un registre du processeur, 1 pour le mouvement inverse, 2 pour l’addition de deux valeurs contenues dans un registre, etc.). Un programme simple pourrait donc être la séquence de chiffres suivante:
0-0-@1000 |
charger dans le registre 0 le contenu de la mémoire à l’adresse 1000 |
Tableau 1: Un programme simple en langage machine
Chapitre 2: Description générale de l’ordinateur
0-1-@1004 |
charger dans le registre 1 le contenu de la mémoire à l’adresse 1004 |
2-0-1-5 |
additionner le contenu des registres 0 et 1 et mettre le résultat dans le registre 5 |
1-5-@1008 |
décharger le contenu du registre 0 dans la mémoire à l’adresse 1008 |
Tableau 1: Un programme simple en langage machine
Dans le tableau ci-dessus, la première colonne contient la valeur chiffrée de chaque instruction, et la deuxième le comportement correspondant. Dans chaque instruction, le premier chiffre est le type d’instruction (chargement, déchargement, addition, ), et les deux autres chiffres sont des numéros de registre ou des adresses mémoire. Par exemple, la première instruction (0-0-@1000) veut dire: charger - dans le registre 0 - le contenu de la mémoire à l’adresse 1000. C’est ce que l’on appelle le langage machine.
2.4 La programmation
Programmer, c’est écrire une suite de chiffre semblable à celle de la table 1. Ecrire des suites de chiffres comme cela est excessivement difficile. Les relire et les corriger est virtuellement impossible. En plus, la séquence de chiffres requise pour faire la même opération sur deux ordinateurs différents (PC, Mac, station) n’est pas la même. C’est pourquoi on a dû inventer des langages de haut niveau, que l’on compile, c’est-à-dire que l’on transforme en langage machine. L’instruction correspondant à l’instruction ci-dessus est par exemple:
NouveauCapital = AncienCapital + Interet ;
Programme 1
La correspondance entre ce programme et la table 1 est la suivante: les cases mémoire @1000, @1004 et
@1008 ont reçu les noms de AncienCapital, Interet et NouveauCapital. Et le programme demande d’additionner l’AncienCapital et l’Interet et de déposer le résultat dans la case mémoire associée au nom NouveauCapital.
Le programme 1 est certainement beaucoup plus lisible: cela provient du fait que l’on a donné un nom en langage courant aux emplacements mémoire, et utilisé le signe ‘+’ conventionnel pour l’addition. Le signe ‘=’ veut simplement dire: ‘copier le résultat à l’emplacement mémoire désigné par le nom NouveauCapital.
Le compilateur se charge de transformer le programme 1 en la séquence d’instruction du tableau 1, en choisissant lui-même un bon endroit dans la mémoire, et en choisissant les bons codes d’instructions. Les compilateurs modernes peuvent aider énormément le programmeur dans sa tâche.
2.5 Un peu d’histoire
Le langage C est un langage déclaratif compilé conçu pour être très efficace et facilement portable d'un ordinateur à l'autre. Ce langage a été mis au point par Brian Kernighan et Dennis Ritchie des Bell Laboratories en 1972. C'est un langage structuré offrant un niveau d'abstraction relativement faible par rapport aux données et opérations réellement manipulées par la plupart des microprocesseurs, ce qui permet d'assurer une grande rapidité d'exécution. C'est pourquoi le langage C est le langage de prédilection pour le développement des systèmes d'exploitation, d'ailleurs le langage C lui-même a été développé pour faciliter le portage du système d'exploitation UNIX sur diverses architectures matérielles. Le langage C est probablement le langage le plus utilisé par les professionnels de la programmation de nos jours, parce qu'il allie les avantages d'un langage de plus haut niveau à ceux de l'assembleur. De plus, la définition du langage C est du domaine public. Les compilateurs commercialisées actuellement par des éditeurs de logiciels sont néanmoins protégées par des droits d'auteur. C'est à la fin de 1983, que Microsoft et Digital Research ont publié le premier compilateur C pour Chapitre 3: Une première session à votre station de travail
micro-ordinateur personnel. L'institut américain de normalisation, ANSI, a ensuite normalisé ce langage en 1989.
D'une syntaxe simple, le langage C a également servi de base à de nombreux langages dérivés plus modernes tels le langage C++ dont la première version date de 1983 ou Objective C qui sont tous deux des extensions orientées objet compatibles avec le langage C. Le langage Java, lui aussi, emprunte l'essentiel de sa syntaxe au langage C. C demeure donc un préalable quasiment incontournable pour qui s'intéresse à la plupart des autres langages plus récents.
3 Une première session à votre station de travail
Voir polycopié donné au premier cours.
4 L’environnement de programmation
Voir polycopié donné au premier cours.
5 Quelques programmes C simples
5.1 Comment fait-on pour écrire sur l’écran?
Ci-dessous on voit le texte du premier exercice. Il écrit “Bonjour Hal” puis “Belle journée” sur la fenêtre de texte.
#include voidmain () { printf("Bonjour Hal\n"); printf("Belle journée"); } |
Programme 2
Ces quelques lignes forment un programme, qui contient les éléments essentiels qui se retrouvent dans tout programme C. Nous allons donc survoler ces différents éléments et nous les détaillerons dans les sections suivantes.
Un programme C est composé de fonctions et de variables. Une fonction est elle-même constituée d'une séquence d'instructions qui indiquent les opérations à effectuer alors que les variables mémorisent les valeurs utilisées au cours du traitement. Les instructions sont elles-mêmes constituées de mots-clés, de variables et de fonctions. Les mots-clés, représentés ici en gras, sont les instructions de base du langage qui permettent au programmeur d’indiquer la structure et le déroulement de son programme. Ces mots-clés sont propres au langage. Un autre langage (Basic, Pascal, ADA) aura d’autres mots-clés.
Les noms donnés aux variables et fonctions sont ce qu’on appelle des identificateurs. Ils doivent commencer par une lettre (majuscule ou minuscule non accentuée) mais peuvent contenir outre des lettres, des chiffres et le caractère souligné _ dans le reste du symbole. En langage C, les caractères majuscules et minuscules ne sont pas équivalents, ainsi printf() et PRINTF() désignent deux fonctions différentes. En règle générale toutefois, on évite d'utiliser des identificateurs ne différant que par leur casse.
Chapitre 5: Quelques programmes C simples
La première ligne contient la directive #include suivi d’un nom de fichier, ici stdio.h, contenant les déclarations nécessaires à l’utilisation de certaines fonctions. Le compilateur dispose ainsi des informations nécessaires pour vérifier si l’appel de la fonction (en l'occurrence printf) est correct.
A la deuxième ligne la construction main() indique le début de définition d'une fonction dénommée main. Tout programme C comporte au minimum une fonction, la fonction main, qui est la fonction principale par laquelle commence l’exécution du programme.
Les accolades { et }délimitent un bloc d'instructions constituant le corps de la fonction main, en l'occurrence, deux instructions printf. La fin de chaque instruction est marquée par un point-virgule ;.
Les mots entre guillemets constituent ce que l'on appelle une chaîne de caractères (character string), et sont imprimés tels quels par l’instruction printfà quelques exceptions près (voir les section 5.2 et 6.3).
Lorsqu’on exécute le programme, comme vous l’avez certainement fait dans le programme d’introduction, les instructions printf affichent le texte qui se trouve entre les guillemets. L’instruction printf("Bonjour Hal\n") affiche donc “Bonjour Hal” dans la fenêtre texte.
5.2 L’instruction printf
La fonction printf ne fait pas partie du langage C au sens strict mais d'une bibliothèque de fonctions standard d'entrées/sorties, stdio, abréviation de Standard Input/Output, qui sont toujours fournies avec le langage, c’est ce qui explique la présence de la directive #include en début de programme. La fonction printf ne provoque pas de retour à la ligne après la chaîne de caractères qu’elle affiche. Pour provoquer un retour à la ligne il faut insérer séquence spéciale \n dans la chaîne de caractères.
#include void main () { printf("Un "); printf("bout de "); printf("texte.\n"); printf("Nouvelle ligne"); } |
Programme 3
Ces instructions écrivent:
Un bout de texte. Nouvelle ligne
Ecran 1
La séquence \n représentant le caractère de saut de ligne est appelée séquence d'échappement. Les séquences d'échappement permettent de représenter des caractères non imprimables ou difficiles à taper. Outre \n on trouve ainsi \t pour le caractère de tabulation (tab), \b pour le caractère de retour en arrière (backspace), \” pour le guillemet et \\ pour le caractère \ lui-même. Ainsi, si l’on veut afficher un texte qui contient un guillemet, on ne peut pas simplement le mettre dans le texte, car il sert également à indiquer la fin de la chaîne, on doit utiliser la séquence d'échappement correspondante:
printf(“Le guillemet \” delimite les chaines”);
Exercice 1.Créer un programme qui affiche dans la fenêtre texte:
Bonjour !
Bonjour !
Bonjour !
Ecran 2
Pour décaler les mots, utilisez des espaces.
5.3 Commentaires
Il est indispensable de mettre des commentaires dans les programmes d’une certaine envergure car il est très difficile de retrouver ce que fait un programme quand on n’a que la liste d’instructions. En C, il est possible de mettre des textes entre les séquences /* et */ ou après la séquence //, pour documenter les programmes directement dans les sources. Ces commentaires ne font pas partie des instructions et sont totalement ignorés par le compilateur.
/* Commentaire qui s’étend sur plusieurs lignes */ // Commentaire sur une ligne |
6 C plus en détail
6.1 Comment mémorise-t-on une valeur?
Les variables sont des espaces de mémoire qui permettent de conserver des nombres ou d’autres éléments (lettres, mots ). Chaque variable est caractérisée par son nom, son type et son contenu. Le nom est un identificateur et doit donc commencer par une lettre, mais peut contenir outre des lettres, des chiffres et le caractère souligné _ dans le reste du symbole. Les variables correspondent plus ou moins à celles qu’on utilise en algèbre, mais le contenu des variables de programme peut être modifié en cours de route. Ne pas confondre les inconnues d’une équation d’algèbre avec une variable de programme. Une variable est en fait un simple récipient dont on peut changer ou lire le contenu.
Une variable qui permet de “compter” est une variable entière. Le programme ci-dessous montre comment déclarer des variables et comment déposer des valeurs dans celles-ci.
#include void main () { int un_nombre; un_nombre = 5; } |
Programme 4
Pour pouvoir manipuler une variable il est nécessaire d'annoncer cette variable au préalable. Cette opération s'appelle une déclaration. Ainsi à la première ligne du corps de ce programme, après l'accolade { on trouve le mot-clé int, qui indique que l'on souhaite déclarer une variable de type entier (integer), suivi du nom donné à cette nouvelle variable.
Toute variable utilisée dans un programme doit avoir été déclarée auparavant.
On peut ainsi déclarer autant de variables que l’on désire. Les déclarations doivent toujours être les premières instructions au début d'un bloc marqué par une accolade ouvrante {. Aucune déclaration ne peut intervenir après une instruction autre qu'une déclaration.
Immédiatement après sa déclaration le contenu d'une variable est indéterminé, dépendant de l’ordinateur sur lequel le programme est exécuté. Lors de l’exécution du programme, on peut y déposer des valeurs provenant de calculs ou de lectures au clavier. Ainsi, l’instruction un_nombre = 5;dépose la valeur 5 dans la variable. Cette instruction s’appelle affectation.
Pour éviter qu'une variable ne prenne une valeur indéterminée jusqu'à sa première affectation, on peut spécifier sa valeur au moment de sa déclaration. Cette construction s'appelle une initialisation:
int un_nombre = 5;
Le type entier associé au mot-clé int, signifie qu'une variable de ce type ne peut contenir que des nombres entiers. Les valeurs extrêmales acceptables pour un tel entier dépendent de l'architecture (ordinateur et système d'exploitation) utilisée. En règle générale, actuellement, les entiers ont une taille de 32 bits ce qui autorise des valeurs de -2'147'483'648 à 2'147'483'647. Pour manipuler des nombres réels, non entiers, on utilise les types float, qui signifie nombre à virgule flottante ou plus simplement flottant, et double, qui signifie flottant à double précision. Un nombre à virgule flottante est une quantité codée sur 32 bits, comprenant au moins six chiffres significatifs, et comprise entre 10-38 et 10+38 environ. Une variable de type float ou double peut ainsi contenir par exemple des valeurs très proches de (mais jamais exactement égales à) ? ou 2 . Un flottant peut posséder des chiffres après la virgule, la virgule étant représentée par un point conformément à l’usage des pays anglo-saxons. Une variable de type flottant, float, et une variable de type entier, int, ont été déclarées dans le programme ci-dessous:
#include void main () { float nombre_reel; int lon; nombre_reel = 5.679 + 6.120; lon = 31645; } |
Programme 5
S’il y a plusieurs variables de même type, elles peuvent être déclarées sur la même ligne, séparées par des virgules comme on le voit dans cette déclaration: int i, j, m1, m2, m3, m4, m5;
L’ordinateur n’annonce en général pas les dépassements de capacité. Si une variable nombre a été déclarée de type int et que l’on effectue un calcul aboutissant à une valeur plus grande que la valeur maximale autorisée: nombre = 1111111 * 2222222; le résultat n’est pas correct car le résultat est plus grand que 231. 1111111 et 2222222 sont bien des entiers mais leur multiplication aboutit à une valeur qui n'est pas représentable par un entier. Cependant à part des cas rares, les entiers, int, suffisent et le problème évoqué ci-dessus n’apparaît pas souvent.
Il existe d'autres types numériques. Ainsi les types long int et short int, que l'on peut abréger en long ou short, représentent des entiers tout comme int mais avec des valeurs minimales et maximales qui peuvent être différentes. En principe un int est un entier représenté dans la taille la plus naturelle pour le microprocesseur utilisé, c'est-à-dire 32 bits sur un microprocesseur 32 bits et 64 bits sur un microprocesseur 64 bits mais ceci dépend aussi du système d'exploitation voire du compilateur (on peut avoir des int de 32 bits sur une machine 64 bits). Dans tous les cas un short fait au moins 16 bits, un long au moins 32. Le fichier limits.h définit les constantes symboliques INT_MIN, INT_MAX, SHRT_MIN, SHRT_MAX, LONG_MIN, LONG_MAX qui indiquent les bornes de chacun de ces types.
On peut également appliquer les qualificatifs signed et unsigned aux types char, int, short et long. Ces qualificatifs indiquent si le type est signé ou non signé ce qui change l'arithmétique et les valeurs maximales autorisées pour une variable du type considéré. Ainsi, une variable de type signed char peut contenir des valeurs allant de -128 à +127 alors qu'une variable de type unsigned char peut contenir des valeurs allant de 0 à 255. Par défaut les types sont signés et le mot-clé signed est donc très peu utilisé en pratique, le mot-clé unsigned est par contre très fréquent. Là encore le fichier limits.h contient des constantes définissant les valeurs maximales admises pour les types non signés: UCHAR_MAX, UINT_MAX, USHRT_MAX et ULONG_MAX On prend rarement assez de précautions quand on manipule un mélange de variables signeés et non signées. Comparer par exemple une variable signée avec une variable non signée peut ainsi donner des résultats surprenants. La plupart du temps le compilateur émet des avertissements à ce sujet.
6.2 Constantes
Les constantes entières tapées dans un programme telles que 125 sont par défaut de type int. On peut toutefois demander qu'elles soient considérées de type long en ajoutant un l ou L à la fin: 125L. Une constante entière trop grande pour tenir dans int est considérée comme un long même si elle n'a pas de l ou L à la fin. Pour désigner une constante non signée on utilise le suffixe u ou U que l'on peut combiner avec le suffixe l ou L pour désigner une constante de type unsigned long: 1245UL
On peut écrire les constantes entières en hexadécimal en les préfixant par 0x ou 0X (zéro X) comme dans 0X12AB. On peut également les écrire en octal (base huit) en les préfixant par un zéro comme dans 0755.
Les constantes contenant une virgule (125.7) ou un exposant (1e2) sont considérées de type double par défaut. On peut cependant demander que de telles constantes soient considérées soit comme un float en ajoutant un suffixe f ou F, soit comme un long double en ajoutant un l ou L.
Une constante de type caractère (char) s'écrit sous forme d'un caractère entre apostrophes: ’a’. La valeur numérique d'une telle constante est la valeur du caractère dans le jeu de caractères de la machine (le plus souvent le code ASCII). Ainsi la valeur numérique de la constante caractère ’0’ est 48. Dans les calculs, les caractères sont traités exactement comme des entiers même si on s'en sert le plus souvent pour les comparer à d'autres caractères.
Attention à ne pas confondre ’a’ qui désigne la constante caractère a ayant pour valeur numérique 97 et “a” qui désigne un tableau de caractères contenant le caractère a suivi d'un caractère ’\0’ (voir section 6.12)
Constantes symboliques. Dans de nombreux programmes, il est agréable et plus clair d’utiliser une constante sous son nom habituel (pi, g ). Pour cela on utilise la directive #define, généralement à l'extérieur du bloc de la fonction main:
#include
#define pi 3.1415626 #define g 9.81
void main ()
{ double rayon, diametre; rayon = 15.0; diametre = 2*pi*rayon;
}
Programme 6
Dans le programme, les constantes s’utilisent comme les variables, à part le fait qu’elles ne peuvent évidemment pas apparaître dans le membre de gauche d’une affectation.
Constantes énumérées. Une énumération est une suite de valeurs entières constantes auxquelles on donne des noms symboliques. Par exemple:
enum fruits { pomme, poire, banane };
Le premier nom d'une énumération vaut zéro, le suivant un, et ainsi de suite, à moins que l'on précise des valeurs explicites. Si l'on ne donne que certaines valeurs, les suivantes se déduisent par incréments successifs de un:
enum mois { jan=1,fev,mar,avr,mai,jun,jul,aou,sep,oct,nov,dec};
Dans cet exemple fev vaut 2, mar vaut 3 et ainsi de suite.
Les noms définis à l'intérieur d'une énumération doivent être distincts.