2010-10-18 7 views
8

¿Por qué la siguiente llamada:printf too smart casting from char to int?

printf("%d %d", 'a', 'b'); 

resultado de las "correctas" 97 98 valores? % d indica que la función tiene que leer 4 bytes de datos, y printf no debería poder decir el tipo de los argumentos recibidos (además de la cadena de formato), entonces ¿por qué no está el número impreso |a||b||junk||junk|?

Gracias de antemano.

+0

% d es un entero con signo, no dice nada sobre el número de bytes implicados ... – leppie

+2

@leppie: Sin embargo, tiene que ser pasado con un número definido de bytes, y 'printf' tiene que elegir un cierto número de los bytes de la pila para él, y estos ciertos números tienen que ser iguales. –

+4

''a'' tiene tipo' int' no 'char'. –

Respuesta

14

En este caso, los parámetros recibidos por printf serán del tipo int.

En primer lugar, cualquier cosa que pase a printf (salvo el primer parámetro) se somete a "promociones" por defecto, lo que significa (entre otras cosas) que char y short son ambos promovidos a int antes de ser pasado. Por lo tanto, incluso si lo que estaba pasando realmente tiene tipo char, cuando llegue a printf tendrá el tipo int. En su caso, está utilizando un literal de caracteres, que ya tiene el tipo int de todos modos.

Lo mismo ocurre con scanf y otras funciones que toman varios parámetros.

En segundo lugar, incluso sin promociones predeterminados, los literales de caracteres en C ya tienen tipo int de todos modos (§6.4.4.4/10):

una constante entera personaje tiene tipo int.

Por lo tanto, en este caso los valores de empezar con el tipo int, y no se promueven - pero incluso si usted empieza con char s, algo así como:

char a = 'a'; 

printf("%d", a); 

... lo printf recibiere Sería del tipo int, no el tipo char de todos modos.

+1

¿Promociones predeterminadas? De Verdad? ¿Desde cuándo los varargs hacen promociones por defecto? ¿No es solo que el tipo de un carácter literal es 'int'? –

+4

Sí y no, sí, un carácter literal tiene tipo 'int', pero incluso si lo asignó a un' char' y lo pasó, 'printf' todavía recibiría un' int', por lo que es bastante irrelevante. –

+0

Justo arriba, Jerry. Gracias. –

4

En C, un literal de caracteres es un valor de tipo int.

0

imprime el ASCII de DEC para los caracteres ingresados ​​por usted.