Всякий раз, когда у вас есть бинарный оператор (один из +
-
*
/
%
<<
>>
&
|
^
==
!=
<
<=
>
>=
) между двумя целыми операндами разных типов, два типа преобразуются к общему типу перед операцией выполняется. Правила принятия решения о преобразованном типе (из раздела 6.3.1.8 стандарта C99):
Если оба операнда имеют один и тот же тип, то дальнейшие преобразования не требуются.
В противном случае, если оба операнда подписали целочисленные типы или оба имеют неподписанные целочисленных типов, операнд с типом меньшего ранга целочисленного преобразования в преобразуется к типу операнда с большим рангом.
В противном случае, если операнд, который имеет беззнаковый целое число типа имеет ранг больше или равный ранг типа другого операнда, то операнд с знаковым целочисленным типа преобразуется к типу операнда с неподписанными целочисленный тип.
В противном случае, если тип операнда с подписью целочисленного типа может представлять все значения типа операнда с целым числом без знака типа, то операнда с целым числом без знака типа преобразуются в тип операнд со знаком целочисленного типа.
В противном случае оба операнда преобразуются в целое число без знака , соответствующее типу операнда со знаком целочисленного типа.
В этом случае char
может быть либо целым типом подписанного, либо без знака - его подпись определяется реализацией. К счастью, хотя int
может представлять все возможные значения char
, независимо от того, подписан или нет char
, если вы находитесь в системе, где char
s - 8 бит, а int
s - не менее 16 бит.
Если char
подписан, то второй пункт выше относится, так что оба операнд преобразуется в int
(типа с более высоким рангом, ранг определяется в несколько сложном образе, но это по существу эквивалентно битового размер типа). Так как 0x98, так как подписанный char
, отрицательный, он преобразуется в целое число -104, который затем меньше 7.
Если вместо char
не подписан, то четвертый пункт применяется вместо этого. Без знака char
будет преобразован в 152 как int
, что больше, чем 7.
Никогда не полагаться на char
s будучи знаком или без знака. Если вам нужны 8-битные целые числа с определенной подписью, используйте явно signed char
или unsigned char
или используйте типы C99 int8_t
и uint8_t
, определенные int <stdint.h>
.
Очень легко укусить тонкие ошибки, вызванные целыми правилами продвижения. Я настоятельно рекомендую вам всегда компилировать с помощью -Wall
с gcc, который предупредит вас о сравнении целых чисел, подписанных и без знака, которые часто являются причиной ошибок.
У этого есть определенный определенный реализацией знак. Иногда он подписывается (на некоторых хостах), иногда (на других хостах) это не так. –
Независимо от того, подписан ли символ или неподписанный, зависит от платформы, компилятора и конфигурации; например, PowerPC ABI предлагает, чтобы char был непознан, а GCC принимает переопределения параметров -fsigned-char'/'-funsigned-char' для переопределения значений по умолчанию для платформы. Портативный код не должен полагаться на (un) подпись char. – ephemient
Компилятор OP обрабатывает свой символ как подписанный. – ChrisW