Multiplicando char e int juntos em c
Pergunta
Hoje eu encontrei o seguinte:
#include <stdio.h>
int main(){
char x = 255;
int z = ((int)x)*2;
printf("%d\n", z); //prints -2
return 0;
}
Então, basicamente, estou recebendo um transbordamento porque o limite de tamanho é determinado pelos operando no lado direito do = sinal ??
Por que não lançá -lo para int antes de multiplicar o trabalho?
Nesse caso, estou usando um char e int, mas se eu usar "longos" e "longos INT" (C99), então recebo um comportamento semelhante. Geralmente é aconselhado a fazer aritmética com operandos de tamanhos diferentes?
Solução
char
pode ser assinado ou não assinado, dependendo do seu compilador.
No seu caso, ele parece ser assinado e 255 está fora do intervalo que pode representar (provavelmente pode representar apenas números de -128 a 127).
Portanto, o problema ocorre quando você atribui 255 ao seu char
Variável -isso resulta em um valor definido por implementação, que no seu caso, parece ser -1.
Quando você multiplica -1 por 2, você recebe -2. Nenhum mistério lá. O elenco para (int)
Nada - tipos mais estreitos do que int
são sempre promovidos a int
ou unsigned int
Antes de quaisquer cálculos serem feitos com eles.
Outras dicas
Parece que o char está assinado em sua plataforma. Então o char x = 255
é efetivamente o mesmo que char x = -1
. O elenco para int não importa.
Tente mudar isso para:
unsigned char x = 255;
Não, você não está obtendo um estouro na segunda linha (multiplicação). O problema é que o seu compilador está usando signed char
por padrão e 255 transbordam e significam -1. Basicamente, você está inicializando a variável x
com o valor de -1. Fundição -1 para int resultará em -1 (signed
Operands será estendido no upcasts, enquanto unsigned
Operandos serão estendidos com zero).
Você pode forçar o char
ser unsigned
adicionando o unsigned
prefixo:
unsigned char x = 255;
As outras respostas explicam muito bem como seu exemplo "funciona", para que não explique isso novamente.
No entanto, deixe -me observar que, se o que você deseja usar é um "número inteiro de 8 bits não assinado", basta usar <stdint.h>
's uint8_t
já (e seus 16, 32, 64 bits companheiros) e manter -se longe de todos os char
s, short
areia int
está neste mundo.