résultat de
printf ("% d \ n", 5.0 + 2);
est 0
mais
int num = 5.0 + 2; printf("%d\n", num);
vaut 7
Quelle est la différence entre les deux?
5 Réponses :
Le résultat de 5.0 + 2
est 7.0
et est de type double
.
Le "% d" consiste à imprimer
int
.
Une spécification de format et un type d'argument incompatibles entraînent un comportement indéfini .
Pour imprimer une valeur float
ou double
avec printf vous devez utiliser le format "%f"
.
Avec
int num = 5.0 + 2;
résultat de printf ("% d \ n", 1.1);
est le résultat de la valeur des déchets de printf ("% d \ n", 5.0);
est 0 Quelle est la différence entre les deux? Merci beaucoup pour votre réponse.
@PWS - 0 n'est pas moins de déchets. Undefined est undefined, point.
@PWS Pas de "garbage", mais pas ce que vous attendez. Comme mentionné, une incompatibilité de format et de type d'argument conduit à un comportement indéfini , qui pourrait théoriquement invoquer démons nasaux ou reformater votre disque dur .
Dans toutes les expressions, chaque opérande a un type. 5.0
est de type double
. 2
est de type int
.
Chaque fois qu'un double et un entier sont utilisés comme opérandes du même opérateur, l'entier est converti silencieusement en double avant le calcul. Le résultat est de type double
.
Et donc vous passez double
à printf
, mais vous lui avez dit d'attendre un int
, puisque vous avez utilisé % d
. Le résultat est un bug, le résultat n'est pas défini.
Mais dans le cas de int num = 5.0 + 2;
, vous obtenez d'abord un résultat comme double code>,
7.0
. Puis forcez une conversion en int
. Ce code équivaut à:
int num = (int)((double)5.0 + (double)2);
Plus de détails ici: Règles de promotion de type implicite
Le résultat de l'expression 5.0 + 2
est de type double
, car au moins l'un des deux opérandes de l'opérateur +
ici est un virgule flottante / valeur double (donc l'autre sera convertie en double
avant l'ajout).
Si vous écrivez printf ("% d \ n", 5.0 + 2)
, vous passerez une valeur en virgule flottante là où le spécificateur de format attend en fait un int
. Cette discordance est un comportement indéfini, et le 0
que vous recevez pourrait être autre chose (un autre numéro, un plantage, un ... quoi que ce soit) aussi.
int num = 5.0 + 2
, en revanche, convertira la double
-valeur résultant de 5.0 + 2
en une valeur intégrale (en supprimant toute partie fractionnaire). Ainsi, la valeur de num
sera 7
et sera - puisque num
est un type intégral - valide en conjonction avec le spécificateur de format % d
alors.
5.0 + 2
est tapé double
.
L'avertissement du compilateur pour
int main() { return _Generic(5.0 + 2, double: 5.0+2); }
devrait vous le dire comme beaucoup si
int main() { return _Generic(5.0 + 2, struct foo: 0); }
compiler sans erreur ne fonctionne pas.
Faire correspondre "% d"
avec un double dans
printf
entraîne un comportement non défini.
Tout résultat est légal, y compris l'effacement de votre disque dur (peu probable à moins que votre programme n'ait déjà une telle fonctionnalité quelque part; si c'est le cas, UB peut bien avoir pour résultat son invocation par inadvertance).
Les conversions arithmétiques habituelles sont implicitement effectuées pour convertir leurs valeurs en un type commun. Le compilateur effectue d'abord la promotion d'entiers; si les opérandes ont encore des types différents, ils sont convertis dans le type qui apparaît le plus haut dans la hiérarchie suivante -
Dans int num = 5.0 + 2;
cet extrait de code, vous ajoutez un flottant avec un entier et le stockez à nouveau en entier. Ainsi, c convertit automatiquement le résultat en entier à stocker dans une variable de type entier. Ainsi, lors de l'impression avec% d, il s'imprime correctement.
Reportez-vous à cette réponse, cela vous aidera plus stackoverflow.com/a/9027033/7865621