Этот код печатает B2
short a=-5;
unsigned short b=-5u;
if(a==b)
printf("A1");
else
printf("B2");
Я читал о целочисленном продвижении, но мне все еще неясно, как это работает в приведенном здесь примере? Может кто-нибудь тщательно опубликовать шаги, которые выполняет компилятор при расширении / усечении значений?
Давайте пройдемся по вашему коду:
short a = -5;
а = -5, что вписывается в короткий. Пока все просто.
unsigned short b = -5u;
-5u означает применять одинарный -
оператор с постоянной 5u. 5u (без знака int) 5, а одинарный -
не продвигает, так что вы получите 4294967291, что составляет 2 ^ 32-5. (Обновление: я ошибся в своем первоначальном ответе; см. Тестовый скрипт, который показывает, что эта версия верна здесь http://codepad.org/hjooaQFW)
Теперь, помещая это в b, оно усекается до беззнакового short (обычно 2 байта), поэтому b = 65531, что составляет 2 ^ 16-5.
if( a == b )
В этой строке a и b обозначены как целые, чтобы сравнение могло произойти правильно. Если бы их повысили до шорт, b мог бы обернуться. Если бы их повысили до неподписанных шорт, они могли бы обернуться.
Это как сказать if( (int) a == (int) b )
, И a = -5, поэтому (int) a = -5 и b = 65531, поэтому (int) b = 65531, потому что целые числа больше, чем шорты.
a == b
a
а также b
оба повышены до int
в приведенном выше выражении.
unsigned short b=-5u;
В этой декларации -5U
преобразуется в unsigned short
посредством целочисленного преобразования (C99, здесь применяется 6.3.1.3p2) и становится большим значением.
(C99, 6.3.1.3p2) «В противном случае, если новый тип является беззнаковым, значение преобразуется путем многократного сложения или вычитания более одного максимального значения, которое может быть представлено в новом типе, до тех пор, пока значение не окажется в диапазоне Новый тип.»
b
значение тогда (unsigned short) ((unsigned int) USHRT_MAX + 1 -5)
который (unsigned short) 65531
если USHRT_MAX
является (unsigned short) 65535
,
Итак, что у вас есть:
(short) -5 == (unsigned short) 65531
что эквивалентно после целочисленного преобразования обоих операндов в:
-5 == 65531
что эквивалентно 0
,
short
в unsigned short
конверсия (таким образом, имеющая рейтинг конверсии)
short
в int
является продвижением (таким образом, имеет звание повышения)
Акции предпочтительнее конверсий из-за рейтинга. Акции происходят во время арифметических и других операций. Преобразования происходят при простом хранении одного целого типа внутри другого. Арифметические операции могут вызывать как преобразования, так и повышения, чтобы привести типы вместе. Для другого примера:
unsigned int u = 2;
int i = 2;
u + i;
i
преобразуется (не повышается) в unsigned
,
Ваше значение преобразуется в большее значение, потому что оно оборачивается из-за unsigned
, Затем они повышены до int
, таким образом a != b
из-за этого.