Valeurs non signées en C
J'ai le code suivant:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
La sortie est:
ffffffff
ffffffff
-1
-1
4294967295
4294967295
Je vois qu'une valeur est interprétée comme signés ou non selon la valeur passée à printf
fonction. Dans les deux cas, les octets sont identiques (ffffffff
). Alors, qu'est-ce que le unsigned
mot?
source d'informationauteur rvillablanca
Vous devez vous connecter pour publier un commentaire.
Attribuer un
int -1
à ununsigned
: Comme-1
ne rentre pas dans la gamme[0...UINT_MAX]
multiples deUINT_MAX+1
sont ajoutées jusqu'à ce que la réponse est dans la gamme. De toute évidenceUINT_MAX
estpow(2,32)-1 or 429496725
sur les OP de la machine de manière à cea
a la valeur de 4294967295.La
"%x"
"%u"
spécificateur s'attend à un correspondantunsigned
. Car elles ne correspondent pas, "Si une spécification de conversion n'est pas valide, le comportement est indéfini.Si aucun argument n'est pas le type correct pour la spécification de conversion, le comportement est indéfini." C11 §7.21.6.1 9. Le printf spécificateur de ne pas changer
b
.La
"%d"
spécificateur s'attend à un correspondantint
. Car elles ne correspondent pas, plus UB.Donné un comportement indéfini, les conclusions ne sont pas pris en charge.
Même avec le même modèle de bits, différents types peuvent avoir des valeurs différentes.
ffffffff
comme ununsigned
a la valeur de 4294967295. Comme unint
selon entier signé de l'encodage, il a la valeur -1, -2147483647 ou à DÉTERMINER. Comme unfloat
il peut être un NAN.unsigned
stocke un nombre entier dans la plage[0 ... UINT_MAX]
. Il n'a jamais une valeur négative. Si le code a besoin d'un nombre non négatif, utilisezunsigned
. Si le code a besoin d'un comptage du nombre qui peut être + ou - 0, utiliserint
.Mise à jour: pour éviter un avertissement du compilateur sur l'affectation d'un signé
int
àunsigned
utilisez le ci-dessous. C'est ununsigned
1u
être annulés - ce qui est bien défini comme ci-dessus. L'effet est le même qu'un-1
mais qui confère au compilateur direct intentions.Avoir
unsigned
dans la déclaration de la variable est plus utile pour les programmeurs eux-mêmes - ne pas traiter les variables comme négatif. Comme vous l'avez remarqué, les deux-1
et4294967295
ont exactement la même représentation binaire sur 4 octets entier. Il est tout au sujet de la façon dont vous voulez traiter ou voir.La déclaration
unsigned int a = -1;
est la conversion de-1
en complément à deux et de l'affectation de la représentation binaire ena
. Leprintf()
spécificateur dex
d
etu
montrent comment la représentation binaire stocké dans la variablea
ressemble dans un format différent.Lors de l'initialisation de
unsigned int a to -1;
cela signifie que vous êtes le stockage de la2's
complément de-1
dans la mémoire dea
.Qui n'est rien mais
0xffffffff
ou4294967295
.C'est pourquoi, lorsque vous imprimez à l'aide de
%x or %u
spécificateur de format vous obtenez cette sortie.En spécifiant ce paramètre une variable de décider sur le minimum et le maximum de valeur qui peut être stockée.
Comme avec
unsigned int
: la plage est à partir de0 to 4,294,967,295
etint
: la plage est à partir de-2,147,483,648 to 2,147,483,647
Pour plus d'informations sur ce paramètre se référer cette
Dans le hexadécimal il ne peut pas obtenir une valeur négative. Donc, il les montre comme ffffffff.
L'avantage de l'utilisation de la version non signée (quand vous savez que les valeurs contenues sera non négatif) est que, parfois, l'ordinateur va détecter des erreurs pour vous (le programme "crash" quand un valeur négative est affecté à la variable).