« Programmation C/Types de base » : différence entre les versions
Contenu supprimé Contenu ajouté
Aucun résumé des modifications |
m <source> -> <syntaxhighlight> (phab:T237267) |
||
Ligne 243 :
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 :
<
#include <stdio.h>
Ligne 255 :
return 0;
}
</syntaxhighlight>
Le résultat du programme est :
Ligne 264 :
De même :
<
#include <stdio.h>
Ligne 276 :
return 0;
}
</syntaxhighlight>
Le résultat du programme peut alors être :
Ligne 314 :
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 :
<
#include <stdio.h>
Ligne 328 :
return 0;
}
</syntaxhighlight>
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 :
<
#include <stdio.h>
Ligne 345 :
return 0;
}
</syntaxhighlight>
Le résultat est alors 100.0, sans aucune erreur d'accumulation et d'arrondis.
Ligne 360 :
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 :
<
/* Ce code peut ne pas fonctionner avec certains compilateurs */
char i;
Ligne 367 :
/* ... */
}
</syntaxhighlight>
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.
Ligne 376 :
Un petit exemple :
<
#include <stdio.h>
Ligne 384 :
return 0;
}
</syntaxhighlight>
Le programme précédent donnera le résultat suivant dans un environnement ASCII :
Ligne 500 :
Voici une manière de rendre illisible un programme utilisant les trigraphes :
<
??=include <stdio.h>
Ligne 508 :
return 0;
??>
</syntaxhighlight>
Par défaut, la plupart des compilateurs désactivent les trigraphes, au cas où vous ne seriez pas encore dissuadé de les utiliser.
Ligne 551 :
Sous sa forme la plus simple, on déclare une chaîne comme une suite de caractères entre guillemets (double quote) :
<
"Ceci est une chaîne de caractère";
""; /* Chaîne vide */
</syntaxhighlight>
Si la chaîne est trop longue, on peut aussi la couper sur plusieurs lignes :
<
"Ceci est une chaîne de caractère, " /* pas de ; */
"déclarée sur plusieurs lignes.";
</syntaxhighlight>
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).
<
"Une chaîne avec des \"guillemets\" et une barre oblique (\\)\n";
</syntaxhighlight>
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 :
<
/* Ce code contient un effet de bord inattendu */
"\x00abcdefghijklmnopqrstuvzxyz"
</syntaxhighlight>
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 :
<
"\x00" "abcdefghijklmnopqrstuvzxyz"
</syntaxhighlight>
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]].
Ligne 586 :
À noter la représentation '''obsolète''' des chaînes de caractères multilignes. À éviter dans la mesure du possible :
<
/* Ce code est obsolete et a eviter */
"Ceci est une chaîne de caractère,\
déclarée sur plusieurs lignes";
</syntaxhighlight>
== Booléens ==
|