Perché scanf () richiede & # 8220;% lf & # 8221; per i doppi, quando printf () va bene con solo & # 8220;% f & # 8221 ;?

StackOverflow https://stackoverflow.com/questions/210590

  •  03-07-2019
  •  | 
  •  

Domanda

Perché scanf () ha bisogno del l in " % lf " quando si legge un double , quando printf () può utilizzare " % f " indipendentemente dal fatto che il suo argomento sia un double o un float ?

Codice di esempio:

double d;
scanf("%lf", &d);
printf("%f", d);
È stato utile?

Soluzione

Perché C promuoverà i float a doppi per funzioni che accettano argomenti variabili. I puntatori non sono promossi a nulla, quindi dovresti usare % lf , % lg o % le (o % la in C99) da leggere in doppio.

Altri suggerimenti

Poiché & # 1057; 99 la corrispondenza tra identificatori di formato e tipi di argomenti in virgola mobile in C è coerente tra printf e scanf . È

  • % f per float
  • % lf per double
  • % Lf per long double

Accade semplicemente che quando gli argomenti di tipo float vengono passati come parametri variadici, tali argomenti vengono convertiti implicitamente nel tipo double . Questo è il motivo per cui negli identificatori di formato printf % f e % lf sono equivalenti e intercambiabili. In printf puoi " uso incrociato " % lf con float o % f con double .

Ma non c'è motivo di farlo in pratica. Non utilizzare % f per printf argomenti di tipo double . È un'abitudine diffusa nata nel C89 / 90 volte, ma è una cattiva abitudine. Usa % lf in printf per double e mantieni % f riservato per gli argomenti float .

scanf deve conoscere la dimensione dei dati puntati da & amp; d per riempirli correttamente, mentre le funzioni variadiche promuovono i float in doppio (non del tutto sicuro del perché ), quindi printf riceve sempre un doppio .

Perché altrimenti scanf penserà che stai passando un puntatore a un float che ha dimensioni inferiori rispetto a un doppio e restituirà un valore errato.

L'uso di un valore float o double in un'espressione in C comporterà comunque un valore che è doppio, quindi printf non può distinguere. Considerando che un puntatore a un doppio deve essere esplicitamente segnalato a scanf come distinto da un puntatore a float, perché ciò che punta al puntatore è ciò che conta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top