Почему unsigned int 1 ниже, чем char y -1?

main() {
    unsigned x = 1;
    char y = -1;

    if (x > y)
        printf("x>y");
    else
        printf("x<=y");
}

Я ожидал x>y, но мне пришлось изменить unsigned int на signed int, чтобы получить ожидаемый результат.


c
person Furqan    schedule 02.07.2011    source источник
comment
символ у=-1; это должно вызвать ошибку, я думаю, что вместо этого должно быть char y = '-1'   -  person Devjosh    schedule 02.07.2011
comment
@Devjosh, нет, ты не прав. '-1' не является допустимым символом.   -  person taskinoor    schedule 02.07.2011
comment
@Devjosh: '-1' выдает предупреждение, потому что на самом деле это '-' и '1' вместе, а не число -1. Последнее игнорируется.   -  person Lekensteyn    schedule 02.07.2011
comment
@Devjosh Нет, на самом деле я помещаю значение (не ASCII) в тип данных со знаком char (от -128 до 127).   -  person Furqan    schedule 02.07.2011
comment
хорошо, спасибо @taskinoor, и Лекенштейн понял :)   -  person Devjosh    schedule 02.07.2011
comment
@Lekensteyn: константы char имеют целочисленный тип, а значение константы char с более чем одним символом определяется реализацией. (ИСО С99 §6.4.4.4 §10)   -  person ninjalj    schedule 02.07.2011
comment
Возможный дубликат сравнения без знака и знака   -  person phuclv    schedule 04.05.2019
comment
@phuclv закрылся в другую сторону   -  person Antti Haapala    schedule 04.05.2019


Ответы (2)


Если char эквивалентно signed char:

  • char повышается до int (Integer Promotions, ISO C99 §6.3.1.1 ¶2)
  • Поскольку int и unsigned int имеют одинаковый ранг, int преобразуется в unsigned int (Арифметические преобразования, ISO C99 §6.3.1.8)

Если char эквивалентно unsigned char:

  • char may be promoted to either int or unsigned int:
    • If int can represent all unsigned char values (typically because sizeof(int) > sizeof(char)), char is converted to int.
    • В противном случае (обычно из-за sizeof(char)==sizeof(int)) char преобразуется в unsigned.
  • Теперь у нас есть один операнд int или unsigned int, а другой — unsigned int. Первый операнд преобразуется в unsigned int.

Целочисленные повышения: выражение типа более низкого ранга, который int преобразуется в int, если int может содержать все значения исходного типа, в unsigned int в противном случае.

Арифметические преобразования: попробуйте преобразовать в более крупный шрифт. Когда возникает конфликт между подписанным и беззнаковым, если более крупный (включая случай, когда два типа имеют одинаковый ранг) тип беззнаковый, используйте беззнаковый. В противном случае используйте signed только в том случае, если он может представлять все значения обоих типов.

Преобразование в целые типы (ISO C99 §6.3.1.3):

Преобразование значения вне диапазона в беззнаковый целочисленный тип выполняется с помощью циклического переноса (модульной арифметики).

Преобразование значения вне диапазона в целочисленный тип со знаком определяется реализацией и может вызывать сигнал (например, SIGFPE).

person ninjalj    schedule 02.07.2011
comment
Отредактировано: умственная отсталость из-за недостатка сна. - person ninjalj; 02.07.2011
comment
+1 подробный и правильный ответ. (И потому, что я почти всегда добавляю +1 к достойным правильным ответам, когда принятый ответ неверен.) - person R.. GitHub STOP HELPING ICE; 02.07.2011

При использовании подписанного и неподписанного в одной операции подписанный был повышен до беззнакового автоматическим преобразованием типа C. Если битовый шаблон -1 считается беззнаковым числом, то это очень большое значение. Итак, x > y ложно.

person taskinoor    schedule 02.07.2011
comment
@taskinoor: не имеет значения, какой битовый шаблон -1 считается беззнаковым числом, важно значение, когда оно преобразуется в беззнаковый тип. - person CB Bailey; 02.07.2011
comment
@ Чарльз Бейли, это то, что я имел в виду. Может быть, мой язык недостаточно хорош. - person taskinoor; 02.07.2011
comment
@taskinoor: Когда вы говорите о битовом шаблоне -1, мне показалось, что вы подразумеваете, что неявное повышение от char до unsigned зависит от базового представления char в реализации (например, дополнения до двух), что неверно. . - person CB Bailey; 02.07.2011
comment
-1 битовый шаблон не имеет значения. Преобразование в беззнаковый — это арифметическая операция, а не повторная интерпретация битового шаблона. - person R.. GitHub STOP HELPING ICE; 02.07.2011