Pourquoi est-ce que scanf()
a besoin de l
dans "%lf
" lors de la lecture d'un double
, lorsque printf()
peut utiliser "%f
", indépendamment de si son argument est un double
ou un float
?
Exemple de code:
double d;
scanf("%lf", &d);
printf("%f", d);
Parce que C encouragera les flottants à doubler pour les fonctions qui prennent des arguments variables. Les pointeurs ne sont pas promus, vous devriez donc utiliser %lf
, %lg
ou %le
(ou %la
en C99) pour lire en double.
Depuis С99, la correspondance entre les spécificateurs de format et les types d'argument à virgule flottante en C est cohérente entre printf
et scanf
. Il est
%f
pour float
%lf
pour double
%Lf
pour long double
Il se trouve que lorsque des arguments de type float
sont passés en tant que paramètres variadiques, ils sont implicitement convertis en type double
. C'est la raison pour laquelle, dans printf
, les spécificateurs de format %f
et %lf
sont équivalents et interchangeables. Dans printf
, vous pouvez "utiliser" %lf
avec float
ou %f
avec double
.
Mais il n'y a aucune raison de le faire réellement dans la pratique. N'utilisez pas %f
à printf
arguments de type double
. C’est une habitude très répandue, née dans les années 89/90, mais c’est une mauvaise habitude. Utilisez %lf
dans printf
pour double
et gardez %f
réservé pour les arguments float
.
scanf
a besoin de connaître la taille des données pointées par &d
pour la remplir correctement, alors que les fonctions variadiques encouragent les flottants à doubler (vous ne savez pas trop pourquoi), donc printf
obtient toujours un double
.
Sinon, scanf pensera que vous passez un pointeur sur un float dont la taille est inférieure à celle d'un double et qu'il renverra une valeur incorrecte.
L'utilisation d'une valeur float ou double dans une expression C aboutira de toute façon à une valeur double. Par conséquent, printf ne peut pas faire la différence. Tandis qu'un pointeur sur un double doit être explicitement signalé à scanf comme distinct d'un pointeur à flottant, car ce que le pointeur pointe est ce qui compte.