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?

Foi útil?

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 chars, shortareia intestá neste mundo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top