Pregunta

Hoy me encontré con lo siguiente:

#include <stdio.h>

int main(){
char x = 255;
int z = ((int)x)*2;

printf("%d\n", z); //prints -2

return 0;

}

Así que básicamente me estoy poniendo un desbordamiento debido a que el límite de tamaño está determinado por los operandos en la parte derecha del signo = ??

¿Por qué no se convierte para int antes de multiplicar el trabajo?

En este caso estoy usando un char e int, pero si uso "largo" y "long long int" (C99), entonces consigo un comportamiento similar. Es por lo general desaconsejó hacer aritmética con operandos de diferentes tamaños?

¿Fue útil?

Solución

char puede ser ya sea con o sin signo, dependiendo de su compilador.

En su caso, parece que está firmado, y 255 está fuera del rango que puede representar (probablemente, sólo puede representar números a partir de -128 a 127).

Así que el problema se produce cuando se asigna a la variable de 255 char -. Esto se traduce en un valor definido por la implementación, que en su caso, parece ser -1

Si se multiplica por -1 2, se obtiene -2. No hay misterio. El reparto de (int) no hace nada -. int tipos más estrechos que siempre son promovidos a int o unsigned int antes de que los cálculos se hacen con ellos

Otros consejos

Parece que Char se firmó en su plataforma. Por lo que el char x = 255 es efectivamente el mismo que char x = -1. El reparto de int no importa.

Trate de cambiar eso a:

unsigned char x = 255;

No, no están recibiendo un desbordamiento en la segunda línea (multiplicación). El problema es que el compilador está utilizando signed char por desbordamientos por defecto y 255 y significará -1. Básicamente, se está inicializando x variable con el valor de -1. Casting -1 a int resultará en -1 (operandos signed obtendrán signo extendido en upcasts mientras que operandos unsigned obtendrán extendida cero).

Se puede forzar el char ser unsigned añadiendo el prefijo unsigned:

unsigned char x = 255;

El otro responde muy bien a explicar cómo su ejemplo "funciona", por lo que no van a explicar que de nuevo.

Sin embargo, permítanme observar que si lo que desea utilizar es un "entero sin signo de 8 bits", el uso justo <stdint.h> de uint8_t ya (y sus 16, 32, compañeros de 64 bits) y mantenerse alejado de todos los chars, shorts y ints en este mundo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top