2010-10-18 5 views
8

Perché la seguente chiamata:printf casting troppo intelligente da char a int?

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

risultato nei "giusti" 97 98 valori? % d indica che la funzione deve leggere 4 byte di dati e printf non dovrebbe essere in grado di indicare il tipo degli argomenti ricevuti (oltre alla stringa di formato), quindi perché il numero stampato non è |a||b||junk||junk|?

Grazie in anticipo.

+0

% d è un numero intero con segno, non dice nulla sul numero di byte coinvolti ... – leppie

+2

@leppie: Tuttavia, deve essere passato con un numero definito di byte e 'printf' deve selezionare un certo numero di byte fuori dallo stack per questo, e questi determinati numeri devono essere uguali. –

+4

''a'' ha tipo' int' non 'char'. –

risposta

14

In questo caso, i parametri ricevuti da printf saranno di tipo int.

Prima di tutto, qualsiasi cosa si passa a printf (tranne il primo parametro) subisce "promozioni di default", che significa (tra le altre cose) che char e short sono entrambi promossi al int prima di essere passato. Quindi, anche se quello che stavi passando aveva tipo char, nel momento in cui è arrivato a printf avrebbe avuto tipo int. Nel tuo caso, stai utilizzando un carattere letterale, che ha già il tipo int.

Lo stesso vale per scanf e altre funzioni che richiedono parametri variadici.

secondo luogo, anche senza promozioni predefinite, letterali di caratteri in C ha già tipo int comunque (§6.4.4.4/10): costante carattere

Un numero intero ha tipo int.

Quindi, in questo caso i valori iniziano con il tipo int, e non sono promossi - ma anche se si è iniziato con char s, qualcosa di simile:

char a = 'a'; 

printf("%d", a); 

... cosa printf riceve sarebbe di tipo int, non di tipo char comunque.

+1

Promozioni predefinite? Veramente? Da quando le vararg fanno promozioni predefinite? Non è solo che il tipo di carattere letterale è 'int'? –

+4

Sì e no - sì, un letterale char ha tipo 'int', ma anche se lo ha assegnato a un' char' e passato, 'printf' riceverebbe ancora un' int', quindi è praticamente irrilevante. –

+0

Giusto, Jerry. Grazie. –

4

In C, un valore letterale char è un valore di tipo int.

0

stampa DEC ASCII per i caratteri immessi dall'utente.