Vi estos dos parámetros en un ejemplo de C en un libro de C, pero el autor no explicó cuál es la diferencia entre los dos. Yo sé eso %f
especifica que un flotador debe tomar su lugar. Intenté buscar esto, pero tuve dificultades para encontrar estos símbolos w. Qué pasa %lf
?
¿Cuál es la diferencia entre %f y %lf en C?
comprometidoandroid
paxdiablo
La respuesta corta es que no tiene ningún impacto en printf
y denota el uso de float
o double
en scanf
.
Para printf
argumentos de tipo float
son promovidos a double
por lo tanto %f
y %lf
se utilizan para double
. Para scanf
Deberías usar %f
por float
y %lf
por double
.
Más detalles para los abogados de idiomas entre nosotros a continuación:
No hay diferencia entre %f
y %lf
en el printf
familia. El estándar ISO C (todas las referencias dentro son de C11), sección 7.21.6.1 The fprintf function
párrafo /7
estados, por la l
modificador (mi énfasis):
Especifica que un siguiente
d
,i
,o
,u
,x
oX
El especificador de conversión se aplica a unlong int
ounsigned long int
argumento; que un siguienten
El especificador de conversión se aplica a un puntero a unlong int
argumento; que un siguientec
El especificador de conversión se aplica a unwint_t
argumento; que un siguientes
El especificador de conversión se aplica a un puntero a unwchar_t
argumento; o no tiene ningún efecto sobre los siguientesa
,A
,e
,E
,f
,F
,g
oG
especificador de conversión.
La razón por la que no necesita modificar el f
especificador es porque ese especificador ya denota un double
del párrafo /8
de esa misma sección donde se enumera el tipo para el %f
especificador:
A
double
el argumento que representa un número de punto flotante se convierte a notación decimal
Eso tiene que ver con el hecho de que los argumentos que siguen a la elipse en el prototipo de función están sujetos a las promociones de argumento predeterminadas según la sección 6.5.2.2 Function calls
párrafo /7
:
La notación de puntos suspensivos en un declarador de prototipo de función hace que la conversión de tipo de argumento se detenga después del último parámetro declarado. Las promociones de argumento predeterminadas se realizan en argumentos finales.
Ya que printf
(y todo el familia de printf
-como funciones) se declara como int printf(const char * restrict format, ...);
con la notación de puntos suspensivos, esa regla se aplica aquí. Las promociones de argumentos predeterminados se tratan en la sección 6.5.2.2 Function calls
párrafo /6
:
Si la expresión que denota la función llamada tiene un tipo que no incluye un prototipo, las promociones de enteros se realizan en cada argumento, y argumentos que tienen tipo
float
son promovidos adouble
. Estas se denominan promociones de argumentos predeterminados.
Para el scanf
familia, exige el uso de un double
preferible a float
. Sección 7.21.6.2 The fscanf function /11
:
Especifica que un siguiente
d
,i
,o
,u
,x
,X
on
El especificador de conversión se aplica a un argumento con puntero de tipo along int
ounsigned long int
; que un siguientea
,A
,e
,E
,f
,F
,g
oG
El especificador de conversión se aplica a un argumento con puntero de tipo adouble
; o que un seguidorc
,s
o[
conversion specifier applies to an argument with type pointer towchar_t
.
This modifies the /12
paragraph of that section that states, for %f
:
Matches an optionally signed floating-point number, infinity, or
NaN
, whose format is the same as expected for the subject sequence of thestrtod
function. The corresponding argument shall be a pointer to floating.
For scanf
, %f
reads into a float
, and %lf
reads into a double
.
For printf
: In C99 and later, they both are identical, and they print either a float
or a double
. In C89, %lf
caused undefined behaviour although it was a common extension to treat it as %f
.
The reason that one specifier can be used for two different types in printf
is because of the default argument promotions; arguments of type float
are promoted to double
when used to call a function and not matching a parameter in a function prototype. So printf
just sees a double
in either case.
The width modifier in %lf is gracefully ignored by printf(). Or, to be more accurate, %f takes a double – varargs will always promote float arguments to double.
Deepesh Dragoneel
For output using the printf family of functions, the %f and %lf specifiers mean the same thing; the l is ignored. Both require a corresponding argument of type double — but an argument of type float is promoted to double, which is why there’s no separate specifier for type float. (This promotion applies only to variadic functions like printf and to functions declared without a prototype, not to function calls in general.) For type long double, the correct format specifier is %Lf.
For input using the scanf family of functions, the floating-point format specifiers are %f, %lf, and %Lf. These require pointers to objects of type float, double, and long double, respectively. (There’s no float-to-double promotion because the arguments are pointers. A float value can be promoted to double, but a float* pointer can’t be promoted to a double* because the pointer has to point to an actual float object.)
But be careful using the scanf functions with numeric input. There is no defined overflow checking, and if the input is outside the range of the type your program’s behavior is undefined. For safety, read input into a string and then use something like strtod to convert it to a numeric value. (See the documentation to find out how to detect errors.)
En lugar de mirar hacia arriba
%f
y%lf
¿intentaste mirar hacia arriba?printf
ofprintf
?– ruakh
16 de septiembre de 2014 a las 4:49
usted puede encontrar esta
printf
(y familia) referencia práctico. Por supuesto que también hay una referencia parascanf
(y familia).– Un tipo programador
16 de septiembre de 2014 a las 4:50
En el estándar C, busque “La función fprintf”, cubre todo
–MM
16 de septiembre de 2014 a las 4:51
Lea la documentación de imprimirf(3) y de escanear(3)
– Basile Starynkevitch
16 de septiembre de 2014 a las 4:51