2010-04-16 4 views
6

Сегодня я нашел следующее:Умножив полукокса и ИНТ вместе в C

#include <stdio.h> 

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

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

return 0; 

} 

Так в основном я получаю переполнение, поскольку предельный размер определяется операндами на правой стороне знак = ??

Почему он не бросает его в int перед умножением работы?

В этом случае я использую char и int, но если я использую «long» и «long long int» (c99), то получаю подобное поведение. Не рекомендуется ли вообще делать арифметику с операндами разных размеров?

ответ

11

char могут быть подписаны или без знака, в зависимости от компилятора.

В вашем случае он подписан, а 255 находится вне диапазона, который он может представлять (вероятно, он может представлять только числа от -128 до 127).

Таким образом, проблема возникает, когда вы назначаете 255 вашей переменной char - это приводит к определенному реализацией значению, которое в вашем случае представляется равным -1.

Когда вы умножаете -1 на 2, вы получаете -2. Таинственности нет. Литой до (int) ничего не делает - типы, более узкие, чем int, всегда относятся к int или unsigned int перед любыми вычислениями с ними.

4

Нет, вы не получаете переполнение во второй строке (умножение). Проблема заключается в том, что ваш компилятор использует signed char по умолчанию и 255 переполнений и будет означать -1. В принципе, вы инициализируете переменную x со значением -1. Листинг -1 для int приведет к -1 (signed операнды получат расширенный знак в upcasts, тогда как unsigned операнды будут иметь нулевое расширение).

Вы можете заставить char быть unsigned путем добавления префикса unsigned:

unsigned char x = 255; 
5

Оказывается, что полукокс подписан на вашей платформе. Таким образом, char x = 255 фактически совпадает с char x = -1. Приведение к int не имеет значения.

Попробуйте изменить что:

unsigned char x = 255; 
3

Другие ответы прекрасно объясняют, как ваш пример «работает», поэтому я больше не буду об этом объяснять.

Однако, позвольте мне заметить, что если то, что вы хотите использовать в «неподписанных 8 битное целое», просто использовать <stdint.h> «s uint8_t уже (и его 16, 32, 64-разрядные компаньонов) и держаться подальше от всех char с , short s и int s в этом мире.

+1

#include для этих типов. – slartibartfast