web-dev-qa-db-fra.com

Pourquoi scanf () a-t-il besoin de "% lf" pour les doublons, alors que printf () accepte uniquement "% f"?

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);
171
raldi

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.

200
MSN

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.

24
AnT

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.

16
Tanktalus

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.

7
Jim Buck

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.

2
fcw