2010-11-16 15 views
3

Qu'est-ce qui se passe ici:Conversion implicite dans C?

printf("result = %d\n", 1); 
printf("result = %f\n", 1); 

sorties:

result = 1 
result = 0.000000 

Si j'assure le type de ces variables avant d'essayer de les imprimer, il fonctionne très bien évidemment. Pourquoi la deuxième instruction d'impression n'est pas implicitement convertie en 1.00000?

Répondre

8

Dans le second cas, vous avez une discordance entre votre chaîne de format et le type d'argument - le résultat est donc indéfini behavior (u) r.

+9

+1 pour une lettre supplémentaire dans "comportement". Les Britanniques l'utilisent comme sauvegarde au cas où quelque chose de méchant arriverait au "o". –

+1

@ Moo-Juice: Aussi pour que le mot ait l'ensemble complet des voyelles disponibles. – caf

+1

@caf: Pourquoi je ne trouve pas le y? =) – Arkku

2

Un comportement indéfini. Un int est traité comme flotteur

+0

ITYM "un int est traité comme un flottant". –

+0

merci j'ai fixé. –

+2

+1 pour le comportement correct de l'orthographe. ;-) –

0

Intéressant, on peut supposer qu'il est très bien si vous pouvez mettre dans « 1.0 »

Je suppose que le printf ne reçoit que l'adresse de la variable, il n'a aucun moyen de savoir ce qu'il était. Mais j'aurais pensé que le compilateur aurait la décence de vous avertir.

+0

Le compilateur ne sait pas quels types la fonction attend. C'est ce qui fait que les fonctions variadiques sont très erronées. –

+0

@Alexander: notez que certains compilateurs, par ex.gcc, ** do ** vérifie la chaîne de format pour printf * et al * et peut émettre des avertissements pour les discordances dans le nombre et/ou le type des arguments. –

1

La réponse courte est que printf n'est pas vraiment C++. Printf est une fonction C qui prend une liste d'arguments variables et applique les arguments fournis à la chaîne de format en fonction des types spécifiés dans la chaîne de format.

Si vous souhaitez effectuer un contrôle de type réel, vous devez utiliser des flux et des chaînes - les alternatives C++ réelles à l'ancienne bonne version de printf.

4

La raison pour laquelle le 1 n'est pas converti en 1.0 est que printf est "juste" une fonction C avec un nombre variable d'arguments, et seul le premier argument (obligatoire) a un type spécifié (const char *). Par conséquent le compilateur "ne peut pas" savoir qu'il devrait convertir l'argument "supplémentaire" il est passé avant queprintf lit réellement la chaîne de format et détermine qu'il doit obtenir un nombre à virgule flottante.

Maintenant, il est vrai votre chaîne de format est une compilation constante de temps et donc le compilateur pourrait faire un cas particulier sur printf et avertir que vous au sujet des arguments incorrects (et, comme d'autres l'ont mentionné, certains compilateurs font , au moins si vous le leur demandez). Mais dans le cas général, il ne peut pas connaître les formats spécifiques utilisés par les fonctions vararg arbitraires, et il est également possible de construire la chaîne de format de manière complexe (par exemple lors de l'exécution). Pour conclure, si vous souhaitez passer un type spécifique en tant qu'argument "variable", vous avez besoin de le convertir.

+0

Notez que pour les arguments variables, 'char' et' short' sont promus 'int' et' float' est promu '' double''. – tomlogic