Différences entre les versions de « Programmation C/Types de base »

m
<source> -> <syntaxhighlight> (phab:T237267)
m (<source> -> <syntaxhighlight> (phab:T237267))
Exemples : On suppose que le type <code>unsigned char</code> est codé sur 8 bits. Alors une valeur de ce type peut aller de 0 à 2<sup>8</sup>-1, soit 255. Par la règle précédente, les conversions se feront donc modulo 255 + 1, soit 256. On considère le programme suivant :
 
<sourcesyntaxhighlight lang="c" line="1">
#include <stdio.h>
 
return 0;
}
</syntaxhighlight>
</source>
 
Le résultat du programme est :
De même :
 
<sourcesyntaxhighlight lang="c">
#include <stdio.h>
 
return 0;
}
</syntaxhighlight>
</source>
 
Le résultat du programme peut alors être :
Le type <code>float</code> en particulier a une précision minimale, qui est bien souvent insuffisante. Voici un exemple classique d'erreur à ne pas faire qui illustre les problèmes liés à la précision des types flottants :
 
<sourcesyntaxhighlight lang="c">
#include <stdio.h>
 
return 0;
}
</syntaxhighlight>
</source>
 
Le résultat est 99,999046, ce qui montre que la précision du type <code>float</code> est en général mauvaise, d'autant plus que le nombre 0,1 n'est pas représentable de manière exacte en binaire<ref>0,1<sub>10</sub> = 0.0001100110011...<sub>2</sub></ref>. Il est ainsi conseillé d'utiliser le type <code>double</code> à la place de <code>float</code> autant que possible. Dans ce cas de figure, il est préférable d'éviter les accumulations d'erreurs infinitésimales, en réécrivant le code de la manière suivante :
 
<sourcesyntaxhighlight lang="c" line="1">
#include <stdio.h>
 
return 0;
}
</syntaxhighlight>
</source>
 
Le résultat est alors 100.0, sans aucune erreur d'accumulation et d'arrondis.
Un autre piège de ce type est qu'il peut être '''de base''' (c'est-à-dire implicitement) <code>signed</code> ou <code>unsigned</code>, au choix du compilateur, ce qui peut s'avérer dangereux (c'est-à-dire difficile à maitriser). Considérez le code suivant :
 
<sourcesyntaxhighlight lang="c">
/* Ce code peut ne pas fonctionner avec certains compilateurs */
char i;
/* ... */
}
</syntaxhighlight>
</source>
 
Dans cet exemple, l'instruction <code>for</code> permet de faire itérer les valeurs entières de <code>i</code> de 100 à 0, incluses. On pourrait naïvement penser '''optimiser''' en utilisant un type <code>char</code>. Sauf que si ce type est implicitement <code>unsigned</code>, la condition <code>i >= 0</code> sera toujours vraie, et tout ce que vous obtiendrez est une boucle infinie. Normalement, tout bon compilateur devrait vous avertir que la condition est toujours vraie et donc vous permettre de corriger en conséquence, plutôt que perdre des heures en débugage.
Un petit exemple :
 
<sourcesyntaxhighlight lang="c">
#include <stdio.h>
 
return 0;
}
</syntaxhighlight>
</source>
 
Le programme précédent donnera le résultat suivant dans un environnement ASCII :
Voici une manière de rendre illisible un programme utilisant les trigraphes :
 
<sourcesyntaxhighlight lang="c">
??=include <stdio.h>
 
return 0;
??>
</syntaxhighlight>
</source>
 
Par défaut, la plupart des compilateurs désactivent les trigraphes, au cas où vous ne seriez pas encore dissuadé de les utiliser.
Sous sa forme la plus simple, on déclare une chaîne comme une suite de caractères entre guillemets (double quote) :
 
<sourcesyntaxhighlight lang="c">
"Ceci est une chaîne de caractère";
""; /* Chaîne vide */
</syntaxhighlight>
</source>
 
Si la chaîne est trop longue, on peut aussi la couper sur plusieurs lignes :
 
<sourcesyntaxhighlight lang="c">
"Ceci est une chaîne de caractère, " /* pas de ; */
"déclarée sur plusieurs lignes.";
</syntaxhighlight>
</source>
 
Deux chaînes côtes à côtes (modulo les espaces et les commentaires) seront concaténées par le compilateur. De plus on peut utiliser le caractère barre oblique inverse (\) pour annuler la signification spéciale de certains caractères ou utiliser des caractères spéciaux (C.f liste ci-dessus).
 
<sourcesyntaxhighlight lang="c">
"Une chaîne avec des \"guillemets\" et une barre oblique (\\)\n";
</syntaxhighlight>
</source>
 
Il est aussi possible d'utiliser la notation hexadécimale et octale pour décrire des caractéres dans la chaîne, il faut néanmoins faire attention avec la notation hexadécimale, car la définition peut s'étendre sur plus de 2 caractéres. En fait, tous les caractères suivant le <code>\x</code> et appartenant à l'ensemble <code>"0123456789abcdefABCDEF"</code> seront utilisés pour déterminer la valeur du caractère (du fait que les caractères d'une chaîne peuvent faire plus qu'un octet). Cela peut produire certains effets de bords comme :
 
<sourcesyntaxhighlight lang="c">
/* Ce code contient un effet de bord inattendu */
"\x00abcdefghijklmnopqrstuvzxyz"
</syntaxhighlight>
</source>
 
Ce code n'insèrera pas un caractère 0 au début de la chaine, mais toute la séquence <code>"\x00abcdef"</code> servira à calculer la valeur du caractère (même si le résultat sera tronqué pour tenir dans un type <code>char</code>). On peut éviter cela en utilisant la concaténation de chaînes constantes :
 
<sourcesyntaxhighlight lang="c">
"\x00" "abcdefghijklmnopqrstuvzxyz"
</syntaxhighlight>
</source>
 
Enfin, les chaînes de caractères faisant appel aux concepts de pointeur, tableau et de zone mémoire statique, leur utilisation plus poussée sera décrite dans la section dédiée aux [[Programmation C/Tableaux|tableaux]].
À noter la représentation '''obsolète''' des chaînes de caractères multilignes. À éviter dans la mesure du possible :
 
<sourcesyntaxhighlight lang="c">
/* Ce code est obsolete et a eviter */
"Ceci est une chaîne de caractère,\
déclarée sur plusieurs lignes";
</syntaxhighlight>
</source>
 
== Booléens ==
1 535

modifications