Question

En C / C ++, à quoi sert un caractère non signé ? En quoi est-il différent d’un caractère normal?

Était-ce utile?

La solution

En C ++, il existe trois types de caractères distincts :

.
  • char
  • caractère signé
  • caractère non signé

Si vous utilisez des types de caractères pour le texte , utilisez le caractère non qualifié :

  • il s'agit du type de littéraux de caractères tels que 'a' ou '0' .
  • c'est le type qui compose les chaînes C telles que " abcde "

Cela fonctionne également comme une valeur numérique, mais il n’est pas précisé si cette valeur est traitée comme signée ou non signée. Méfiez-vous des comparaisons de caractères par le biais d'inégalités - même si vous vous limitez à l'ASCII (0-127), vous êtes en sécurité.

Si vous utilisez des types de caractères comme nombres , utilisez:

  • caractère signé , ce qui vous donne au moins la plage allant de -127 à 127. (-128 à 127 est commun)
  • caractère non signé , ce qui vous donne au moins la plage de 0 à 255.

"Au moins", car la norme C ++ ne donne que la plage minimale de valeurs que chaque type numérique doit couvrir. sizeof (char) doit être égal à 1 (c'est-à-dire un octet), mais un octet peut en théorie être par exemple 32 bits. sizeof indiquerait toujours sa taille sous la forme 1 , ce qui signifie que vous pourriez disposer de sizeof (char). == sizeof (long) == 1 .

Autres conseils

Cela dépend de la mise en oeuvre, car le standard C ne définit PAS la signature de char . Selon la plate-forme, le caractère peut être signé ou non signé . Vous devez donc demander explicitement caractère signé ou caractère non signé si votre implémentation en dépend. Utilisez simplement char si vous souhaitez représenter des caractères de chaînes, car cela correspond à ce que votre plate-forme place dans la chaîne.

La différence entre caractère signé et caractère non signé est conforme à vos attentes. Sur la plupart des plates-formes, char signé sera un numéro de complément à 8 bits deux allant de -128 à 127 et char non signé sera un entier non signé de 8 bits ( 0 à 255 ). Notez que la norme n'exige PAS que les types char aient 8 bits, seulement ce sizeof (char) renvoie 1 . Vous pouvez obtenir le nombre de bits dans un caractère avec CHAR_BIT dans limits.h . Il n’existe que peu de plates-formes aujourd’hui où ce sera autre chose que 8 , cependant.

Il existe un joli résumé de ce problème ici .

Comme d'autres l'ont mentionné depuis que je publie cette publication, vous feriez mieux d'utiliser int8_t et uint8_t si vous voulez vraiment représenter de petits entiers.

Parce que j'estime que c'est vraiment nécessaire, je veux juste énoncer quelques règles de C et C ++ (elles sont les mêmes à cet égard). Tout d’abord, tous les bits de char non signé participent à la détermination de la valeur s’il existe un objet char non signé. Deuxièmement, unsigned char est explicitement déclaré non signé.

Maintenant, j'ai discuté avec quelqu'un de ce qui se passe lorsque vous convertissez la valeur -1 de type int en caractère non signé . Il a refusé l'idée que le caractère non signé résultant ait tous ses bits définis sur 1, car il craignait la représentation des signes. Mais il n'est pas obligé. La règle suivante indique immédiatement que la conversion fait ce qui est prévu:

  

Si le nouveau type n'est pas signé, la valeur est convertie en ajoutant ou en répétant   en soustrayant un de plus que la valeur maximale pouvant être représentée dans le nouveau type   jusqu'à ce que la valeur se situe dans la plage du nouveau type. ( 6.3.1.3p2 dans un brouillon C99)

C'est une description mathématique. C ++ le décrit en termes de modulo calcul, qui obéit à la même règle. Quoi qu'il en soit, ce qui garanti, c'est que tous les bits du nombre entier -1 sont égaux à un avant la conversion. Alors, qu'est-ce que nous avons pour pouvoir prétendre que le caractère non signé résultant a tous ses bits CHAR_BIT devenus 1?

  1. Tous les bits participent à la détermination de sa valeur, c’est-à-dire qu’il n’ya pas de bits de remplissage dans l’objet.
  2. L'ajout d'une seule fois UCHAR_MAX + 1 à -1 donnera une valeur dans la plage, à savoir UCHAR_MAX

C'est assez, en fait! Donc, chaque fois que vous voulez avoir un caractère non signé ayant tous ses bits un, vous faites

unsigned char c = (unsigned char)-1;

Il s'ensuit également qu'une conversion ne pas ne fait que tronquer des bits de poids fort. L’événement privilégié pour le complément à deux est qu’il s’agit là d’une troncature, mais que ce n’est pas nécessairement le cas pour les autres représentations de signe.

Par exemple, l'utilisation du caractère non signé :

Le

caractère non signé est souvent utilisé en infographie, qui attribue très souvent (mais pas toujours) un octet à chaque composant couleur. Il est courant de voir une couleur RVB (ou RVBA) représentée par 24 (ou 32) bits, chacun un caractère non signé . Les valeurs unsigned char étant comprises dans la plage [0,255], elles sont généralement interprétées comme suit:

  • 0 signifie l'absence totale d'une composante de couleur donnée.
  • 255 signifiant 100% d'un pigment de couleur donné.

Ainsi, vous vous retrouveriez avec le rouge RVB sous la forme (255,0,0) - > (100% rouge, 0% vert, 0% bleu).

Pourquoi ne pas utiliser un caractère signé ? L'arithmétique et le transfert de bits deviennent problématiques. Comme expliqué précédemment, la plage d'un char signé est essentiellement décalée de -128. Une méthode très simple et naïve (la plupart du temps inutilisée) pour convertir RVB en niveaux de gris consiste à faire la moyenne des trois composantes de couleur, mais cela peut poser problème lorsque les valeurs des composantes de couleur sont négatives. Le rouge (255, 0, 0) fait la moyenne de (85, 85, 85) lorsqu’on utilise l’arithmétique chars non signés . Cependant, si les valeurs étaient caractères signés (127, -128, -128), nous nous retrouverions avec (-99, -99, -99), ce qui serait (29, 29, 29) dans notre unsigned char , ce qui est incorrect.

Si vous souhaitez utiliser un caractère sous forme de petit entier, la méthode la plus sûre consiste à utiliser les types int8_t et uint8_t .

le caractère signé est compris entre -128 et 127; Le caractère non signé va de 0 à 255.

char sera équivalent à un caractère signé ou à un caractère non signé, selon le compilateur, mais est d'un type distinct.

Si vous utilisez des chaînes de style C, utilisez simplement char . Si vous devez utiliser des caractères pour l'arithmétique (assez rare), spécifiez explicitement signé ou non signé pour la portabilité.

Les caractères

char et chars non signés ne sont pas garantis d'être du type 8 bits sur toutes les plates-formes mais ils sont également garantis d'une taille supérieure ou égale à 8 bits. Certaines plates-formes possèdent des octets 9 bits, 32 bits ou 64 bits. . Cependant, les plates-formes les plus courantes de nos jours (Windows, Mac, Linux x86, etc.) ont des octets de 8 bits.

En termes de valeurs directes, un caractère standard est utilisé lorsque les valeurs sont comprises entre CHAR_MIN et CHAR_MAX , tandis qu'un caractère non signé fournit le double de la plage à l'extrémité positive. . Par exemple, si CHAR_BIT est égal à 8, la plage de char est uniquement garantie sur [0, 127] (car il peut être signé ou non), tandis que le caractère non signé sera [0, 255] et le caractère signé sera [-127, 127].

En ce qui concerne son utilisation, les normes permettent aux objets de POD (données anciennes simples) d’être convertis directement en un tableau de caractères non signés. Cela vous permet d'examiner la représentation et les modèles de bits de l'objet. La même garantie de sécurisation du type n'existe pas pour char ou char signé.

caractère non signé n'accepte que des valeurs positives .... comme 0 à 255

où comme

caractère signé prend les valeurs positives et négatives .... comme -128 en +127

Un caractère non signé est une valeur d'octet (non signé) (0 à 255). Vous pensez peut-être à " char " en termes d'être un "caractère" mais c'est vraiment une valeur numérique. Le " caractère " régulier est signé, vous avez donc 128 valeurs et ces valeurs sont mappées sur des caractères utilisant le codage ASCII. Mais dans les deux cas, ce que vous stockez en mémoire est une valeur d'octet.

Si vous aimez utiliser différents types de longueur et de signature spécifiques, vous êtes probablement mieux avec uint8_t, int8_t, uint16_t, etc. simplement parce qu'ils font exactement ce qu'ils disent.

Un caractère non signé utilise le bit réservé au signe d’un caractère normal comme un autre nombre. Cela modifie la plage en [0 - 255] par opposition à [-128 - 127].

Généralement, les caractères non signés sont utilisés lorsque vous ne souhaitez pas de signe. Cela fera une différence lorsqu’il s'agira de déplacer des bits (shift étend le signe) ou d’autres choses lorsqu’il s’agit d’un caractère sous forme d’octet plutôt que de l’utiliser sous forme de nombre.

unsigned char est le cœur de toute tromperie. Dans presque tous les compilateurs pour toutes les plateformes, un caractère non signé est simplement un BYTE. Un entier non signé de (généralement) 8 bits. qui peut être traité comme un petit entier ou un paquet de bits.

De plus, comme quelqu'un l'a déjà dit, la norme ne définit pas le signe d'un caractère. vous avez donc 3 caractères différents " char " types: caractère, caractère signé, caractère non signé.

Un certain Google a trouvé this , où les gens en ont discuté.

Un caractère non signé est essentiellement un octet unique. Vous pouvez donc utiliser cette option si vous avez besoin d’un octet de données (par exemple, vous souhaitez peut-être l’utiliser pour définir des indicateurs à transmettre à une fonction, comme cela se fait souvent dans l’API Windows).

cité de "le livre de la programmation c" livre:

Le qualificatif signé ou non signé peut être appliqué à un caractère ou à un entier. numéros non signés sont toujours positifs ou nuls, et obéissent aux lois de l'arithmétique modulo 2 ^ n, où n est le nombre de bits dans le type. Ainsi, par exemple, si les caractères sont de 8 bits, les variables de caractères non signés ont des valeurs entre 0 et 255, tandis que les caractères signés ont des valeurs comprises entre -128 et 127 (dans les deux cas). complément machine.) Que les caractères simples soient signés ou non signés dépend de la machine, mais les caractères imprimables sont toujours positifs.

le caractère non signé prend uniquement des valeurs positives: 0 à 255 le caractère signé prend des valeurs positives et négatives: -128 à +127

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top