Как сравнивается целое число без знака и литерал в C? - PullRequest
3 голосов
/ 21 февраля 2020

Я делаю следующее сравнение:

uint32_t value = 1000;

if(value < 100)
{
  // do something
}

Что получает в данном случае что? Преобразуется ли значение в целое число? 100 преобразуется в целое или целое число без знака?

Ответы [ 2 ]

6 голосов
/ 21 февраля 2020

Во-первых, все числовые c константы имеют тип. В случае константы 100, поскольку она является десятичной, не имеет суффикса и может помещаться в диапазоне int, константа имеет тип int.

Как выполняется сравнение продиктовано обычными арифметическими c преобразованиями . В частности, правила преобразования для целочисленных типов указаны в разделе 6.3.1.8p1 C стандарта следующим образом:

... целочисленные продвижения выполняются на обоих операнды.
Затем к продвинутым операндам применяются следующие правила:

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

Предполагается, что на вашей платформе int 32 бита, что делает uint32_t таким же, как unsigned int, поэтому вы используете в выражении тип со знаком и тип без знака того же размера. В этом случае применяется третий вышеприведенный пункт, а именно значение 100 (которое имеет тип int) преобразуется в unsigned int, а затем значения сравниваются.

В этом случае значение 100 также находится в диапазоне unsigned int, поэтому преобразование действительного значения отсутствует. Если бы вместо этого было что-то вроде -100, это значение не находится в диапазоне unsigned int, что означает, что значение будет преобразовано в этот диапазон. Опять же, предполагая, что 32-битное int значение будет 2 32 - 100.

0 голосов
/ 21 февраля 2020

Если два целочисленных выражения имеют одинаковый ранг, как в вашем примере, при условии, что тип uint32_t является псевдонимом для типа unsigned int, тогда тип со знаком преобразуется в тип без знака. То есть целочисленный литерал 100, имеющий тип int со знаком, преобразуется в тип unsigned int.

Из стандарта C (6.3.1.1 Логические значения, символы и целые числа)

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

И (6.3.1.8 Обычная арифметика c преобразования)

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

...