web-dev-qa-db-fra.com

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 peux voir qu'une valeur est interprétée comme signée ou non signée en fonction de la valeur passée à la fonction printf. Dans les deux cas, les octets sont les mêmes (ffffffff). Alors, à quoi sert le mot unsigned?

15
rvillablanca

Affectez un int -1 à une unsigned: Comme -1 ne correspond pas à la plage [0...UINT_MAX], des multiples de UINT_MAX+1 sont ajoutés jusqu'à ce que la réponse soit dans la plage. Evidemment, UINT_MAX est pow(2,32)-1 or 429496725 sur la machine de l'OP, donc a a la valeur 4294967295.

    unsigned int a = -1;

Le spécificateur "%x", "%u" s'attend à une unsigned correspondante. Comme ils ne correspondent pas, "Si une spécification de conversion n'est pas valide, le comportement n'est pas défini. Si l'un des arguments n'est pas du type correct pour la spécification de conversion correspondante, le comportement est non défini." C11 §7.21.6.1 9. Le spécificateur printf ne change pas b.

    printf("%x\n", b);  // UB
    printf("%u\n", b);  // UB

Le spécificateur "%d" s'attend à une int correspondante. Puisque ceux-ci ne correspondent pas, plus UB.

    printf("%d\n", a);  // UB

Compte tenu d'un comportement non défini, les conclusions ne sont pas supportées.


dans les deux cas, les octets sont les mêmes (ffffffff).

Même avec le même motif binaire, différents types peuvent avoir des valeurs différentes. ffffffff en tant que unsigned a la valeur 4294967295. En tant que int, en fonction du codage de l'entier signé, il a pour valeur -1, -2147483647 ou TBD. En tant que float, il peut s'agir d'un NAN .

à quoi sert Word non signé?

unsigned stocke un nombre entier dans la plage [0 ... UINT_MAX]. Il n'a jamais de valeur négative. Si le code nécessite un nombre non négatif, utilisez unsigned. Si le code nécessite un nombre de comptage pouvant être +, - ou 0, utilisez int.


Mise à jour: pour éviter un avertissement du compilateur concernant l'affectation d'une int signée à unsigned, utilisez la méthode ci-dessous. Ceci est une unsigned1u en cours de négation - ce qui est bien défini comme ci-dessus. L'effet est identique à -1, mais transmet les intentions directes du compilateur.

unsigned int a = -1u;
12
chux

Avoir unsigned dans la déclaration de variable est plus utile pour les programmeurs eux-mêmes - ne traitez pas les variables comme négatives. Comme vous l'avez remarqué, -1 et 4294967295 ont exactement la même représentation binaire pour un entier de 4 octets. Tout dépend de la façon dont vous voulez traiter ou les voir.

L'instruction unsigned int a = -1; est en train de convertir -1 en complément à deux et d'assigner la représentation binaire dans a. Les spécificateurs printf(), x, d et u montrent comment la représentation binaire stockée dans la variable a se présente sous un format différent.

0
Donotalo

Lorsque vous initialisez unsigned int a to -1;, cela signifie que vous stockez le complément 2's de -1 dans la mémoire de a.
Ce qui n'est rien d'autre que 0xffffffff ou 4294967295.

Par conséquent, lorsque vous l'imprimez en utilisant le spécificateur de format %x or %u, vous obtenez cette sortie. 

En spécifiant la signature d'une variable pour décider de la limite minimale et maximale de valeur pouvant être stockée. 

Comme avec unsigned int: la plage est de 0 to 4,294,967,295 et int: la plage est de -2,147,483,648 to 2,147,483,647

Pour plus d'informations sur la signature, référez-vous this

0
Santosh A