C'est parce que %d
s'attend à un int
mais vous avez fourni un flotteur.
Utilisez %e
/ %f
/ %g
pour imprimer le flotteur.
Pourquoi 0 est imprimé: le nombre à virgule flottante est converti en double
avant l'envoi vers printf
. Le nombre 1234.5 en double représentation en petit boutiste est
00 00 00 00 00 4A 93 40
A %d
consomme un entier 32 bits, donc un zéro est imprimé. (En guise de test, vous printf("%d, %d\n", 1234.5f);
pourriez obtenir la sortie 0, 1083394560
.)
Quant à savoir pourquoi le float
est converti en double
, comme le prototype de printf l'est int printf(const char*, ...)
, à partir du 6.5.2.2/7,
La notation des points de suspension dans un déclarateur de prototype de fonction provoque l'arrêt de la conversion de type d'argument après le dernier paramètre déclaré. Les promotions d'argument par défaut sont effectuées sur les arguments de fin.
et à partir du 6.5.2.2/6,
Si l'expression qui désigne la fonction appelée a un type qui n'inclut pas de prototype, les promotions d'entiers sont effectuées sur chaque argument et les arguments qui ont un type float
sont promus en double
. On les appelle les promotions d'argument par défaut .
(Merci Alok d'avoir découvert cela.)
printf
c'est une fonction variadique, et la norme dit que pour les fonctions variadiques, afloat
est converti endouble
avant de passer.printf()
appelle un comportement indéfini .Techniquement parlant, il n'y a pas de the
printf
, chaque bibliothèque implémente la sienne, et par conséquent, votre méthode pour essayer d'étudierprintf
le comportement de ce que vous faites ne sera pas d'une grande utilité. Vous pourriez essayer d'étudier le comportement deprintf
sur votre système, et si tel est le cas, vous devriez lire la documentation et regarder le code source pour savoirprintf
s'il est disponible pour votre bibliothèque.Par exemple, sur mon Macbook, j'obtiens la sortie
1606416304
avec votre programme.Cela dit, lorsque vous passez a
float
à une fonction variadique, lefloat
est passé comme adouble
. Donc, votre programme équivaut à avoir déclaré ena
tant que fichierdouble
.Pour examiner les octets de a
double
, vous pouvez voir cette réponse à une question récente ici sur SO.Faisons cela:
Lorsque j'exécute le programme ci-dessus, j'obtiens:
Ainsi, les quatre premiers octets de la
double
se sont avérés être 0, ce qui peut être la raison pour laquelle vous avez obtenu0
la sortie de votreprintf
appel.Pour des résultats plus intéressants, nous pouvons modifier un peu le programme:
Lorsque j'exécute le programme ci-dessus sur mon Macbook, j'obtiens:
Avec le même programme sur une machine Linux, j'obtiens:
la source
int
arguments sont passés dans des registres différents desdouble
arguments.printf
with%d
prend l'int
argument qui est 42 et le second%d
imprime probablement des fichiers indésirables puisqu'il n'y avait pas de secondint
argument.Le
%d
spécificateur ditprintf
d'attendre un entier. Ainsi, les quatre premiers octets (ou deux, selon la plate-forme) du float sont interprétés comme un entier. S'ils se trouvent être zéro, un zéro est impriméLa représentation binaire de 1234,5 est quelque chose comme
Avec un compilateur C qui représente en
float
fait des valeurs doubles IEEE754, les octets seraient (si je ne me trompais pas)Sur un système Intel (x86) avec peu d'extrémité (c'est-à-dire l'octet le moins significatif venant en premier), cette séquence d'octets est inversée de sorte que les quatre premiers octets sont à zéro. Autrement dit, ce qui
printf
s'imprime ...Consultez cet article de Wikipedia pour la représentation en virgule flottante selon IEEE754.
la source
C'est à cause de la représentation d'un flottant en binaire. La conversion en entier le laisse avec 0.
la source
Parce que vous avez invoqué un comportement indéfini: vous avez violé le contrat de la méthode printf () en lui mentant sur ses types de paramètres, de sorte que le compilateur est libre de faire ce qu'il veut. Cela pourrait faire sortir le programme "dksjalk est un ninnyhead !!!" et techniquement, ce serait toujours vrai.
la source
La raison en est que
printf()
c'est une fonction assez stupide. Il ne vérifie pas du tout les types. Si vous dites que le premier argument est unint
(et c'est ce avec quoi vous dites%d
), il vous croit et il ne prend que les octets nécessaires pour un fichierint
. Dans ce cas, en supposant que votre machine utilise quatreint
et huit octetsdouble
(lefloat
est converti en un à l'double
intérieurprintf()
), les quatre premiers octets dea
seront juste des zéros, et cela sera imprimé.la source
Il ne convertira pas automatiquement le flottant en entier. Parce que les deux ont un format de stockage différent. Donc, si vous souhaitez convertir, utilisez le typage (int).
la source
Puisque vous l'avez également marqué avec C ++, ce code effectue la conversion comme vous vous y attendez probablement:
Production:
la source
%d
est décimal%f
est flottantvoir plus de ceux-ci ici .
Vous obtenez 0 car les flottants et les entiers sont représentés différemment.
la source
Il vous suffit d'utiliser le spécificateur de format approprié (% d,% f,% s, etc.) avec le type de données approprié (int, float, string, etc.).
la source
Vous voulez% f pas% d
la source
hey il fallait imprimer quelque chose donc il a imprimé un 0. Rappelez-vous en C 0 c'est tout le reste!
la source
Ce n'est pas un entier. Essayez d'utiliser
%f
.la source