2010-02-16 32 views
9

Estaba trabajando en este programa y noté que usar% f para un doble y% d para un flotador me da algo completamente diferente. ¿Alguien sabe por qué sucede esto?C printf usando% d y% f

int main() 
{ 
float a = 1F; 
double b = 1; 

printf("float =%d\ndouble= %f", a, b); 
} 

Esta es la salida

float = -1610612736 
double = 190359837192766135921612671364749893774625551025007120912096639276776057269784974988808792093423962875123204096.0000 
+0

Gracias a todos por los comentarios. Ahora lo entiendo. – user69514

Respuesta

4

Debido a la forma en que funcionan los parámetros variables, C no tiene idea del tipo de valor que está realmente pasándolo aparte de %d y %f. Cuando pasa un parámetro de variable básicamente está haciendo (void*)&myvalue porque ni el compilador ni la función en tiempo de ejecución pueden determinar el tipo de la variable, excepto lo que se da en la cadena de formato. Entonces, aunque hay una conversión implícita disponible, el compilador no sabe que es necesaria.

Bueno, el doble tiene 8 bytes en la mayoría de los sistemas, mientras que el flotante tiene 4 bytes. Entonces los dos tipos no son compatibles con los binarios. Y es como tratar de interpretar una cadena como un doble, o algún otro tipo incompatible.

+2

Correcto, pero en realidad no se trata de compatibilidad entre 'float' y' double' específicamente. En realidad, los argumentos variados del tipo 'float' siempre se promueven a' double' antes de pasar, lo que significa que el tipo 'float' no está involucrado aquí. Ambos valores que se pasan a 'printf' tienen el tipo' double'. Dentro del primero se interpreta como un 'int' (debido al especificador'% d'). La incompatibilidad entre 'int' y' double' es lo que está causando el comportamiento indefinido observado. – AnT

3

Tiene que ver con representaciones internas de datos. Está intentando imprimir un flotante como si fuera un int, que tiene una representación interna (binaria) completamente diferente.

La caja doble es similar. Probablemente tenga basura (cualquier dato) después de la variable flotante. Esa basura se interpreta como parte del doble valor.

4

%d significa decimal y espera un argumento de tipo int (o algún tipo entero con signo más pequeño que luego se promociona). Los tipos de punto flotante float y double se pasan de la misma manera (promovidos a double) y ambos usan %f. En C99 también puede usar %lf para significar el tamaño más grande de double, pero esto es puramente cosmético (observe que con scanf no se produce ninguna promoción y esto realmente hace una diferencia).

+0

Bueno, esto es cierto http://codepad.org/labE8lgy, pero me pregunto cómo funciona en realidad ... – Earlz

0

% d imprime un entero, por lo que su printf interpreta su variable a como un int.

Con gcc 3.4.6, obtengo 0's para ambos valores con su código (después de sacar la F de la inicialización, ya que eso llevó a un error de compilación). Sospecho que esto tiene que ver con la parte de la variable que se interpreta como un int siendo 0, y luego el compilador se confunde ... (probablemente haya una explicación mejor, pero no puedo pensar en ello).

Usando% f para ambas impresiones variables 1.000000 para ambas variables para mí.

se puede encontrar una lista de los caracteres de conversión cerca de la parte inferior esta página:

http://www.exforsys.com/tutorials/c-language/managing-input-and-output-operations-in-c.html

+0

El error del compilador asociado con 'F' se debe a que no se puede adjuntar a un entero (por ejemplo,' 1.0F' está bien). – RastaJedi