Por que scanf() precisa de “%lf” para duplas, quando printf() funciona apenas com “%f”?
-
03-07-2019 - |
Pergunta
Por que é isso scanf()
precisa do l
em "%lf
"ao ler um double
, quando printf()
pode usar "%f
"independentemente de seu argumento ser um double
ou um float
?
Código de exemplo:
double d;
scanf("%lf", &d);
printf("%f", d);
Solução
Porque C promoverá flutuadores para duplas para funções que recebem argumentos variáveis. Ponteiros não são promovidos a nada, então você deveria estar usando %lf
, %lg
ou %le
(ou %la
em C99) para ler em duplas.
Outras dicas
Desde С99, a correspondência entre especificadores de formato e tipos de argumentos de ponto flutuante em C é consistente entre printf
e scanf
.Isso é
%f
parafloat
%lf
paradouble
%Lf
paralong double
Acontece que quando argumentos do tipo float
são passados como parâmetros variados, tais argumentos são convertidos implicitamente para o tipo double
.Esta é a razão pela qual em printf
especificadores de formato %f
e %lf
são equivalentes e intercambiáveis.Em printf
você pode "uso cruzado" %lf
com float
ou %f
com double
.
Mas não há razão para realmente fazer isso na prática.Não use %f
para printf
argumentos do tipo double
.É um hábito generalizado que nasceu na época de C89/90, mas é um mau hábito.Usar %lf
em printf
para double
e mantenha %f
reservado para float
argumentos.
scanf
precisa saber o tamanho dos dados que estão sendo apontados por &d
Para preenchê -lo corretamente, enquanto as funções variadas promovem carros alegóricos para duplas (sem muita certeza do porquê), então printf
está sempre recebendo um double
.
Porque, de outra forma, o SCANF pensa que você está passando um ponteiro para um flutuador, que é um tamanho menor que um duplo e retornará um valor incorreto.
O uso de um valor float ou um duplo em uma expressão C resultará em um valor que é duplo de qualquer maneira, para que o Printf não possa dizer a diferença. Enquanto um ponteiro para um duplo deve ser explicitamente sinalizado para escanear como distinto de um ponteiro para flutuar, porque o que o ponteiro aponta é o que importa.