Сравнение неподписанного целого и подписанного символа - PullRequest
4 голосов
/ 23 февраля 2011

Я пытаюсь сравнить беззнаковое целое с подписанным символом следующим образом:

int main(){
  unsigned int x = 9;
  signed char y = -1;
  x < y ? printf("s") : printf("g");
  return 0;
}

Я ожидал, что o / p будет "g".Вместо этого его "s".Какой вид конвертации здесь делается?

Ответы [ 5 ]

23 голосов
/ 23 февраля 2011

Раздел 6.3.1.8, Обычные арифметические преобразования, из C99 детализирует неявные целочисленные преобразования.

Если оба операнда имеют одинаковый тип, дальнейшее преобразование не требуется.

Это не считается, так как они разных типов.

В противном случае, если оба операнда имеют целочисленные типы со знаком или оба имеют целочисленные типы без знака, операнд с типом ранга преобразования с меньшим целым числом преобразуется в тип операнда с большим рангом.

Это не считается, так как один подписан, а другой без знака.

В противном случае, если операнд с целым типом без знака имеет ранг, больший или равный рангу типа другого операнда, то операнд с целым типом со знаком преобразуется в тип операнда с целым типом без знака.

Бинго. x имеет более высокий ранг, чем y, поэтому y повышен до unsigned int. Это означает, что он трансформируется из -1 в UINT_MAX, значительно больше 9.

Остальные правила не применяются, так как мы нашли наш матч, но я добавлю их для полноты:

В противном случае, если тип операнда с целым типом со знаком может представлять все значения типа операнда с целым типом без знака, то операнд с целым типом без знака преобразуется в тип операнда с целым числом со знаком типа.

В противном случае оба операнда преобразуются в целочисленный тип без знака, соответствующий типу операнда с целочисленным типом со знаком.


Ранги, относящиеся к этому вопросу, приведены ниже. Все ранги подробно описаны в C99, раздел 6.3.1.1, Boolean, символ и целые числа , так что вы можете обратиться к этому для получения дополнительной информации.

звание long long int должно быть больше звания long int, что должно быть больше, чем ранг int, который должен быть больше, чем ранг short int, который должен быть больше, чем ранг signed char.

Ранг char равняется рангу signed char и unsigned char.

2 голосов
/ 23 февраля 2011

Запустил следующий код:

int main(){
  unsigned int x = 9;
  signed char y = -1;
  printf("%u\n", (unsigned int)y);
  x < (unsigned int)y ? printf("s") : printf("g");
  return 0;
}

Вывод:

4294967295
s

После приведения y принимает очень большое значение. Вот почему вывод s.

2 голосов
/ 23 февраля 2011

Мне кажется, y повышен до unsigned int, что становится большим значением (из-за переноса). Следовательно условие выполнено.

1 голос
/ 28 июня 2011

См. Комментарий by caf по ссылке ниже: Когда вы конвертируете число вне диапазона в тип без знака, оно вводится в диапазон путем многократного добавления или вычитания более одного максимального значения типа -

C: преобразовать подписанный в неподписанный

В этом случае UINT_MAX + 1, который на вашей платформе равен 4294967296, добавляется к -1, чтобы получить 4294967295.

1 голос
/ 23 февраля 2011

Значение символа повышается до unsigned int со значением MAX_UINT, которое больше 9.

...