c casting printf garbage

c - Resultado inesperado de printf



casting garbage (4)

int a=5; float b=3.5; printf("%d",b); printf("/n%f",a);

¿Alguien puede decirme por qué este código muestra resultados inesperados (basura / n3.5)?


Debido a que la variable es un tipo int, mientras que usted está especificando una cadena de formato para un tipo de letra flotante, y viceversa para la variable b .

Nota :

%d es para tipo entero

%f es para tipo de flotador

Deberías usar :

int a=5; float b=3.5; printf("%f",b); printf("/n%d",a);


Está pasando un float para la cadena de formato %d , pero printf espera una int .

printf es una función de lista de argumentos variable: printf(const char *format_string,...);

Esto significa que el resto de los argumentos posteriores a la cadena de formato pueden ser de cualquier tipo y número, y el compilador no sabe qué deberían ser. Depende del programador proporcionar argumentos que sean del tipo que printf espera. Lo que printf espera está determinado por la cadena de formato. Cuando da un %d en su cadena de formato, la función printf esperará que el siguiente argumento sea un int . Como pasas float , es probable que algo extraño suceda. Por ejemplo, esos bytes que componen el número de punto flotante se pueden tratar como si fueran un int , lo que no le dará ningún valor significativo.

En realidad, es un poco más complicado que eso. Existen reglas especiales sobre cómo se pasan los parámetros a las funciones de argumento variable. Una de las reglas es que los valores float se pasan como double . Lo que significa que su valor float primero se convierte en un double antes de pasarse a printf . Lo más probable es que un double sea ​​ocho bytes en su plataforma, mientras que un int es solo cuatro. Entonces, la función printf podría tratar los primeros cuatro bytes de su double valor como int .

Lo que es incluso peor es que en la siguiente línea, se está pasando un int donde se espera un double . Lo que significa que la función printf podría tratar los primeros cuatro bytes de tu int como parte del double , y luego leer cuatro bytes más que ni siquiera formaban parte de tus argumentos.

Los detalles de lo que realmente ocurre son específicos de la plataforma. El lenguaje simplemente indica que no debe pasar el tipo de argumento incorrecto y no garantiza que sucederá si lo hace.


Formato error incorrecto de cadena, de acuerdo con sus declaraciones de b :

printf("%d",b); <-- "b is float" Wrong! printf("/n%f",a); <-- "a is an int" Wrong! -- Undefined behavior

debiera ser:

printf("%f",b); printf("/n%d",a);

P: ¿Por qué estás obteniendo esa salida?

Se debe a un comportamiento indefinido de tu código:

De ESTÁNDAR INTERNACIONAL © ISO / IEC ISO / IEC 9899: 201x

7.16.1 Macros de acceso a la lista de argumentos variables

(página 270)

7.16.1.1 La macro va_arg

[...] Si no hay un próximo argumento real, o si el tipo no es compatible con el tipo del siguiente argumento real (como se promueve de acuerdo con las promociones del argumento predeterminado), el behavior is undefined , excepto en los siguientes casos:
- un tipo es un signed integer type , el otro es el tipo unsigned integer correspondiente, y el valor es representable en ambos tipos;
- un tipo es puntero a void y el otro es un puntero a un tipo de carácter


int main() { int a=5; float b=3.5; printf("%f",b); //Use %f printf("/n%d",a); // Use %d }

Consulte: printf

El especificador de formato incorrecto para printf lleva un comportamiento indefinido en la mayoría de los casos.

Sin embargo, dado que printf es una función variadica, y los argumentos para funciones variadic se someten al molde de argumento predeterminado. Al igual, un char se convierte en un int.