Ho il codice seguente:
char x = -1; int y = x; printf("%u\n", x); printf("%u\n", y);
L’output è:
4294967295 4294967295
Non capisco perché x può avere un tale valore. So che il valore massimo di un char unsigned è 255 e per un char firmato 127. Come può essere 4294967295?
Per funzioni come printf
che usano argomenti variadici, qualsiasi tipo di integrale più piccolo di un int
( char
e short
) viene implicitamente promosso a int
. Lo stesso è vero con i numeri in virgola mobile, float
è promosso a double
.
Quindi, il tuo char
viene esteso al segno con un valore int
con valore -1
, e dal momento che lo stai stampando come non firmato, nel complemento a 2 ottieni UINT_MAX
.
Modifica: come segue, se il tuo char
impostato su unsigned (questo dipende dal tuo compilatore / piattaforma), la risposta sarà invece 255
. Quando si verifica la promozione, il valore sarà esteso a zero anziché esteso al segno.
La variabile ha il valore -1. ma hai specificato% u (unsigned int) nel printf
int è a 32 bit quindi 2 ^ 32 = 4294967296 => -1 + 4294967296 = 4294967295 spero che tu lo capisca.
Stai utilizzando male un identificatore di formato e invocando un comportamento indefinito a causa di ciò. La mia comprensione è che, in ogni caso, il numero di convertiti alla rappresentazione binaria del complimento è uguale per -1 o 4294967295. Ecco perché% u per le stampe firmate 4294967295 ignorando -ve bit più a sinistra. Quando viene utilizzato% d per l’int firmato, utilizza il bit più a sinistra come flag -ve e stampa -1. Allo stesso modo% u per il valore senza segno delle stampe non firmate ma% d induce a trattare il numero come firmato e quindi stampa -1
Se il qualificatore di input è signed
, fai attenzione al bit del segno, se il bit del segno è 1, otterrai un valore negativo. Sebbene x
sia signed char
, si sta aspettando 1 byte
valore di 1 byte
, ma si ottiene un valore di 4 byte
causa del meccanismo di copia bit di segno .
x valore:
x = -1 = 0000 0000 0000 0000 0000 0000 1111 1111 | sign bit, this bit get's copied into remaining bytes, so it becomes like = 1111 1111 1111 1111 1111 11111 1111 1111 => calculates this => 4294967295 = | sign bit , now you are printing in %u format ie unsigned so it will ignore signed bit and you are getting big value.
Lo stesso se si stampa in formato %d
o %i
printf("%d\n", x); // it prints -1 bcz %d will check sign bit which is 1 ie it will prints -ve value, so it's prints -1
Ho solo cercato di spiegare il motivo per cui si sta ottenendo tale output, ma è un undefined behaviour
come menzionato in alcuni commenti se non si utilizza l’identificatore di formato corretto. puoi riferirti a diversi standard C.
EDIT: per giustificare il mio punto (macchina Linux) consideriamo sotto il codice
int main() { unsigned char x = -1; printf("%u\n",x); /*In above printf input is unsigned, so compiler won't check sign bit, even though sign bit is 1, result will be +ve only. */ printf("%d\n",x);//some of you may expects -1 because of %d, it's wrong. /* In above printf it's printing 255 not because of format specifier, it's because of your input qualifier(which is unsigned in this case) */ return 0; }