C сравнения char и int - PullRequest
       35

C сравнения char и int

4 голосов
/ 18 июня 2009

В приведенном ниже блоке кода, какое неточное преобразование происходит в операторе if для 7? Хотелось бы, чтобы в конечном итоге это было (0x98

char minstogo = 0x98;
if(minstogo <= 7) {
   DoMyStuff();
}

Ответы [ 6 ]

16 голосов
/ 18 июня 2009

Когда у вас есть бинарный оператор (один из + - * / % << >> & | ^ == != < <= > >=) между двумя целыми операндами разных типов, оба типа преобразуются в общий тип перед выполнением операции. Правила выбора типа преобразования (из раздела 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 подписаны или не подписаны. Если вам нужны 8-разрядные целые числа определенной подписи, явно используйте signed char или unsigned char или используйте типы C99 int8_t и uint8_t, определенные int <stdint.h>.

Очень легко быть укушенным незначительными ошибками, вызванными целочисленными правилами продвижения. Я настоятельно советую вам всегда компилировать с -Wall с помощью gcc, который предупредит вас о сравнении целых чисел со знаком и без знака, которые часто являются причиной ошибок.

6 голосов
/ 18 июня 2009

Скорее всего, здесь происходит то, что char является значением со знаком и, следовательно, 0x98 регистрируется как отрицательное число. Следовательно, оно меньше 7

Также в этом сценарии 7 не будет преобразовано. Вместо этого символ будет расширен до того же целочисленного типа, что и 7, и тогда будет выполнено сравнение.

1 голос
/ 18 июня 2009

Он будет оцениваться так же, как и 0x98 <= 7, если для типа платформы char по умолчанию не указано значение со знаком, а CHAR_BIT равно 8. В этом случае значение minstogo будет отрицательным, а minstogo <= 7 будет истинным.

1 голос
/ 18 июня 2009

Поскольку символы представлены в виде восьмибитного байта, установка minstogo на 0x98 представляет собой двоичное значение 10011000. Знаковый бит установлен, это отрицательное целочисленное значение. Вы, вероятно, хотите, чтобы беззнаковый символ для теста оценивался как ложный.

0 голосов
/ 18 июня 2009

0x98 - 152.

Поскольку вы объявили "char", а не "unsigned char", вы пытаетесь присвоить 152 типу с диапазоном -128 - 127 .

Это будет переполнением и даст вам отрицательное число, которое будет <7 (0x07). </p>

0 голосов
/ 18 июня 2009

Используя ваш компилятор с текущими настройками, тип char является знаком: и поскольку бит старшего разряда (0x80) его значения установлен, это значение является отрицательным. Когда minstogo расширяется, этот отрицательный знак сохраняется (посредством расширения знака), и поэтому minstogo расширяется до отрицательного целого числа (например, 0xFF98), которое меньше 7.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...