5
votes

pourquoi le résultat de (double + int) est 0 (langage C)

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?


1 commentaires

Reportez-vous à cette réponse, cela vous aidera plus stackoverflow.com/a/9027033/7865621


5 Réponses :


9
votes

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;


3 commentaires

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 .



6
votes

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


0 commentaires

3
votes

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.


0 commentaires

1
votes

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).


0 commentaires

0
votes

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 -

 entrez la description de l'image ici

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.

moins l'imprimer à l'aide de% d. Ici, le spécificateur de format ne correspond pas à un résultat inattendu.


0 commentaires