Je l’ai Voici un programme simple :
La condition `` est toujours true. Comment est-ce possible ?
Il fonctionne très bien si je change de la macro :
Quelqu'un peut-il indiquer le numéro ?
Je l’ai Voici un programme simple :
La condition `` est toujours true. Comment est-ce possible ?
Il fonctionne très bien si je change de la macro :
Quelqu'un peut-il indiquer le numéro ?
C'est assez subtile.
Chaque littéral entier dans votre programme a un type. Le type a est réglementée par une table dans 6.4.4.1:
Suffix Decimal Constant Octal or Hexadecimal Constant
none int int
long int unsigned int
long long int long int
unsigned long int
long long int
unsigned long long int
Si un nombre littéral ne peut pas s'adapter à l'intérieur de la valeur par défaut int
type, il va tenter à la prochaine grande type comme indiqué dans le tableau ci-dessus. Donc, pour l'ordinaire entier décimal littéraux il va comme:
int
long
long long
.Hex littéraux de se comporter différemment si! Si le littéral ne peut pas s'adapter à l'intérieur d'un type signé comme int
, il va d'abord essayer d' unsigned int
avant de passer à essayer de plus grands types. Voir la différence dans le tableau ci-dessus.
Ainsi, sur un système 32 bits, votre littérale 0x80000000
est de type unsigned int
.
Cela signifie que vous pouvez appliquer unaire -
de l'opérateur sur le littéral, sans invoquer de mise en œuvre définies par le comportement, comme vous le feriez lors de l'débordement d'un entier signé. Au lieu de cela, vous obtenez la valeur 0x80000000
, une valeur positive.
bal < INT32_MIN
invoque l'habitude de l'arithmétique de conversions et le résultat de l'expression -0x80000000
est promu unsigned int
de long long
. La valeur 0x80000000
est conservé et 0 est inférieure à 0x80000000, d'où le résultat.
Lorsque vous remplacez le littéral avec 2147483648L
vous utilisez la notation décimale et donc le compilateur ne pioche pas de unsigned int
, mais plutôt essaie de l'adapter à l'intérieur d'un long
. Aussi le L suffixe dit que vous voulez un long
si possible. La L suffixe a effectivement des règles similaires si vous continuez à lire mentionnés table dans 6.4.4.1: si le numéro ne correspond pas à l'intérieur de la demande long
, il n'est pas dans les 32 bits de cas, le compilateur va vous donner un long long
où il a mis en place.
Cet entier littéral 0x80000000
type unsigned int
.
Selon la Norme (6.4.4.1 constantes entières)
5 Le type d'une constante entière est la première de l'correspondant liste dans laquelle sa valeur peut être représentée.
Et cette constante entière peut être représenté par le type d' unsigned int
.
De sorte que cette expression
-0x80000000
a le même unsigned int
type. En outre, il a la même valeur
0x80000000
dans le complément à deux de la représentation qui calcule de la façon suivante
-0x80000000 = ~0x80000000 + 1 => 0x7FFFFFFF + 1 => 0x80000000
Cela a un effet secondaire s'écrire par exemple
int x = INT_MIN;
x = abs( x );
Le résultat sera à nouveau INT_MIN
.
Ainsi, dans cette condition
bal < INT32_MIN
il est comparé 0
avec unsigned valeur 0x80000000
convertis en type long long int, selon les règles de l'arithmétique habituelle des conversions.
Il est évident que 0 est inférieure à 0x80000000
.
D'un point de confusion se produit dans la pensée de l' -
fait partie de la constante numérique.
Dans le code ci-dessous 0x80000000
est la constante numérique. Son type est de déterminer uniquement sur cela. L' -
est appliquée par la suite et ne change pas le type.
#define INT32_MIN (-0x80000000)
long long bal = 0;
if (bal < INT32_MIN )
Raw sans fioritures constantes numériques sont positifs.
Si c'est décimal, puis le type attribué est le premier type qui va la tenir: int
, long
, long long
.
Si la constante est en octal ou en hexadécimal, il obtient le premier type qui la tient: int
, unsigned
, long
, unsigned long
, long long
, unsigned long long
.
0x80000000
, OP système obtient le type d' unsigned
ou unsigned long
. De toute façon, c'est un certain type non signé.
-0x80000000
est également une valeur non nulle et d'être certain type non signé, il est plus grand que 0. Lorsque le code compare à un long long
, les valeurs ne sont pas modifiées sur les 2 côtés de la comparer 0 < INT32_MIN
est vrai.
Une autre définition évite ce curieux comportement
#define INT32_MIN (-2147483647 - 1)
Nous marchons dans la terre de fantaisie pour un temps où l' int
et unsigned
sont de 48 bits.
Ensuite, 0x80000000
correspond int
et est donc le type d' int
. -0x80000000
est un nombre négatif et le résultat de l'impression est différente.
[Réel]
Depuis 0x80000000
s'inscrit dans certains type non signé devant un type signé, comme il est juste plus grand que some_signed_MAX
encore dans some_unsigned_MAX
, c'est un certain type non signé.
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.