Prova 285212672ULL
; se lo scrivi senza suffissi, troverai che il compilatore lo considera come un normale intero. La ragione per cui sta funzionando in una variabile è perché il numero intero viene assegnato a un unsigned long long
nel compito, in modo che il valore passato a printf()
sia il tipo giusto.
E prima di chiedere, no, il compilatore probabilmente non è abbastanza intelligente per capirlo dal "%llu
"nella stringa di formato printf()
. Questo è un diverso livello di astrazione. Il compilatore è responsabile per la sintassi del linguaggio , printf()
la semantica non fanno parte del sintassi, si tratta di una funzione di libreria di runtime (non è diverso in realtà dalle proprie funzioni, tranne che è incluso nella serie).
si consideri il seguente codice per un int a 32 bit e 64 a lungo non firmato sistema lungo:
#include <stdio.h>
int main (void) {
printf ("%llu\n",1,2);
printf ("%llu\n",1ULL,2);
return 0;
}
che emette:
8589934593
1
Nel primo caso, i due interi a 32-bit 1 e 2 sono inseriti nello stack e printf()
interpreta che come un singolo valore ULL 64 bit, 2 x 2 + 1. L'argomento 2
viene incluso inavvertitamente nel valore ULL.
Nel secondo, si spinge effettivamente il valore 1 a 64 bit e un numero intero superfluo a 32 bit 2
, che viene ignorato.
Si noti che questa "uscita di passaggio" tra la stringa del formato e gli argomenti effettivi è una cattiva idea. Qualcosa di simile:
printf ("%llu %s %d\n", 0, "hello", 0);
rischia di schiantarsi perché il puntatore a 32 bit "hello"
sarà consumato dal %llu
e %s
cercherà di de-riferimento l'argomento finale 0
. La seguente "immagine" illustra questo (supponiamo che le celle siano a 32 bit e che la stringa "ciao" sia archiviata a 0xbf000000.
What you pass Stack frames What printf() uses
+------------+
0 | 0 | \
+------------+ > 64-bit value for %llu.
"hello" | 0xbf000000 |/
+------------+
0 | 0 | value for %s (likely core dump here).
+------------+
| ? | value for %d (could be anything).
+------------+
ma penso compilatore è abbastanza intelligente per capire% u in formato printf, prova printf ("% d% u", ~ 0, ~ 0) .. entrambi stamperanno i valori come previsto. – sud03r
No - questi tipi di dati hanno le stesse dimensioni - è printf() capito che - prova % d con 'a'. – paxdiablo
Pax: Va bene, i caratteri letterali sono costanti intere. – caf