Un tampon d'octets doit-il être signé char ou unsigned char ou simplement un tampon char ? Y a-t-il des différences entre le C et le C++ ?
Gracias.
Un tampon d'octets doit-il être signé char ou unsigned char ou simplement un tampon char ? Y a-t-il des différences entre le C et le C++ ?
Gracias.
Si vous avez l'intention de stocker des données binaires arbitraires, vous devez utiliser la fonction unsigned char
. C'est le seul type de données dont la norme C garantit l'absence de bits de remplissage. Tous les autres types de données peuvent contenir des bits de remplissage dans leur représentation objet (c'est-à-dire celle qui contient tous les bits d'un objet, au lieu de seulement ceux qui déterminent une valeur). L'état des bits de remplissage n'est pas spécifié et ils ne sont pas utilisés pour stocker des valeurs. Ainsi, si vous lisez en utilisant char
Dans le cas de données binaires, les choses seraient réduites à la plage de valeurs d'un caractère (en interprétant uniquement les bits de valeur), mais il peut toujours y avoir des bits qui sont simplement ignorés mais qui sont toujours là et lus par memcpy
. Tout comme les bits de remplissage dans les objets struct réels. Type unsigned char
est garantie de ne pas en contenir. Cela découle de 5.2.4.2.1/2
(C99 TC2, n1124 ici) :
Si la valeur d'un objet de type char est traitée comme un entier signé lorsqu'elle est utilisée dans un fichier la valeur de l'objet
CHAR_MIN
est le même que celui deSCHAR_MIN
et la valeur deCHAR_MAX
est le même que celui deSCHAR_MAX
. Sinon, la valeur deCHAR_MIN
est égal à 0 et la valeur deCHAR_MAX
est le même que celui deUCHAR_MAX
. _La valeurUCHAR_MAX
est égal à2^CHAR_BIT − 1
_
Il ressort de la dernière phrase qu'il n'y a plus de place pour les bits de remplissage. Si vous utilisez char
comme le type de votre tampon, vous avez également le problème des débordements : L'attribution explicite d'une valeur quelconque à l'un de ces éléments, qui se situe dans l'intervalle de 8
bits - on peut donc s'attendre à ce qu'une telle affectation soit correcte - mais pas dans la plage d'un char
qui est CHAR_MIN
.. CHAR_MAX
si une telle conversion déborde et provoque des résultats définis par la mise en œuvre, y compris l'augmentation des signaux.
Même si les problèmes relatifs à ce qui précède ne se manifesteraient probablement pas dans les mises en œuvre réelles (ce serait une très mauvaise qualité de la mise en œuvre), il est préférable d'utiliser le bon type dès le début, à savoir unsigned char
.
Pour les chaînes de caractères, cependant, le type de données de choix est char
qui sera compris par les fonctions string et print. Utilisation de signed char
à ces fins me semble être une mauvaise décision.
Pour plus d'informations, lisez this proposal
qui contiennent un correctif pour une prochaine version du standard C qui nécessitera finalement signed char
n'a pas non plus de bits de remplissage. C'est déjà incorporé dans le document de travail .
Un tampon d'octets doit-il être signé signé, un char non signé ou simplement un char ou simplement un tampon char ? Y a-t-il des différences entre C et C++ ?
Une différence mineure dans la façon dont la langue le traite. A énorme différence dans la façon dont la convention le traite.
char
= ASCII (ou UTF-8, mais le signe est gênant) textuel donnéesunsigned char
= octetsigned char
= rarement utiliséEt il y a un code qui s'appuie sur sur une telle distinction. Il y a une semaine ou deux, j'ai rencontré un bogue où les données JPEG étaient corrompues parce qu'elles étaient transmises à l'option char*
version de notre fonction d'encodage Base64 - qui a "utilement" remplacé tous les UTF-8 invalides dans la "chaîne". Le passage à BYTE
alias unsigned char
était tout ce qu'il fallait pour le réparer.
Ça dépend.
Si le tampon est destiné à contenir du texte, il est probablement plus logique de le déclarer comme un tableau de char
et laissez la plate-forme décider pour vous si elle est signée ou non par défaut. Vous aurez ainsi moins de difficultés à faire entrer et sortir les données de la bibliothèque d'exécution de l'implémentation, par exemple.
Si le tampon est destiné à contenir des données binaires, cela dépend de l'utilisation que vous comptez en faire. Par exemple, si les données binaires sont en réalité un tableau emballé d'échantillons de données qui sont des mesures signées de 8 bits à virgule fixe de l'ADC, alors signed char
serait le mieux.
Dans la plupart des cas réels, le tampon n'est que cela, un tampon, et vous ne vous souciez pas vraiment des types des octets individuels parce que vous avez rempli le tampon dans une opération de masse, et vous êtes sur le point de le passer à un analyseur syntaxique pour interpréter la structure de données complexe et faire quelque chose d'utile. Dans ce cas, déclarez-la de la manière la plus simple.
S'il s'agit en fait d'un tampon d'octets 8 bits, plutôt que d'une chaîne de caractères dans la locale par défaut de la machine, alors j'utiliserais uint8_t
. Non pas qu'il y ait beaucoup de machines sur lesquelles un caractère n'est pas un octet (ou un octet un octet), mais le fait d'indiquer "ceci est un tampon d'octets" plutôt que "ceci est une chaîne" est souvent une documentation utile.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.