Moltiplicando char e int insieme in C
Domanda
Oggi ho trovato la seguente:
#include <stdio.h>
int main(){
char x = 255;
int z = ((int)x)*2;
printf("%d\n", z); //prints -2
return 0;
}
Quindi, fondamentalmente sto ottenendo un overflow perché il limite di dimensione è determinata dalle operandi sul lato destro del segno = ??
Perché non il cast a int prima di moltiplicare il lavoro?
In questo caso sto usando un char e int, ma se uso "lungo" e "long long int" (C99), allora ottengo un comportamento simile. E 'generalmente sconsigliati fare aritmetica con operandi di diverse dimensioni?
Soluzione
char
può essere sia firmato o non firmato, a seconda del compilatore.
Nel tuo caso, sembra essere firmato, e 255 è fuori del campo può rappresentare (probabilmente, può rappresentare solo numeri da -128 a 127).
Quindi, il problema si verifica quando si assegna 255 alla variabile char
-. Ciò si traduce in un valore definito dall'implementazione, che nel tuo caso, sembra essere -1
Quando si moltiplicano -1 per 2, si ottiene -2. Nessun mistero lì. Il cast di (int)
non fa nulla -. Tipi più strette di int
sono sempre promossi int
o unsigned int
prima che i calcoli sono fatti con loro
Altri suggerimenti
Sembra che char è firmato sulla vostra piattaforma. Così il char x = 255
è effettivamente la stessa char x = -1
. Il cast a int non importa.
Provare a cambiare quello a:
unsigned char x = 255;
No, non sono sempre un overflow sulla seconda riga (moltiplicazione). Il problema è che il compilatore sta usando signed char
per default e 255 overflow e significherà -1. In sostanza, si inizializza x
variabile con il valore di -1. Casting -1 a int comporterà -1 (operandi signed
avranno accesso esteso in upcasts mentre operandi unsigned
otterrà zero estesa).
È possibile forzare il char
essere unsigned
aggiungendo il prefisso unsigned
:
unsigned char x = 255;
Le altre risposte ben spiegare come il vostro esempio "opere", quindi non mi spiegheranno che ancora una volta.
Tuttavia, mi permetta di osservare che se ciò che si desidera utilizzare è un "unsigned 8 bit integer", solo l'uso <stdint.h>
di uint8_t
già (e le sue 16, 32, compagni a 64 bit) e tenere lontano da tutti i char
s, short
s e int
s in questo mondo.