Странный вопрос, касающийся целочисленного типа C и спецификатора printf () - PullRequest
0 голосов
/ 10 мая 2011

Хорошо, я знаю, что этот вопрос может показаться странным, но все же я хотел его демистифицировать.

1.) Тип int в C может хранить число в диапазоне от -2147483648 до 2147483647.

2.) Если мы добавим unsigned перед ним, диапазон станет от 0 до 2147483647.

3.) Дело в том, почему мы вообще пытаемся использовать ключевое слово unsigned, когда приведенный ниже код действительно может работать.


Код:

#include <stdio.h>

int main(void)
{
    int num = 2147483650;

    printf("%u\n" , num);

    return 0;
}


4.) Как вы видите, я все еще могу распечатать целое число как тип без знака, если я использую спецификатор %u, и он выведет мне значение 2147483650.

5.) Даже если я создам другой целочисленный тип со значением 50 и суммирую его с num, хотя это переполнение, но я все равно могу распечатать правильное значение суммы с помощью спецификатора %u. Так почему unsigned ключевое слово по-прежнему необходимо ??

Спасибо, что потратили время на чтение моего вопроса.

Ответы [ 4 ]

5 голосов
/ 10 мая 2011
  1. Нет, это верно только на определенных платформах (где int - 32-битный, дополнение 2-х).

  2. Нет, в этом случае диапазон будет от 0 до 4294967295.

  3. Этот код демонстрирует неопределенное поведение .

  4. См. 3.

  5. См. 2. и 3.

2 голосов
/ 10 мая 2011

Рассматривая только вопрос 3 «Почему мы не используем unsigned», рассмотрим следующий фрагмент программы:

int main(void) {

  int num = MAX_INT;
  num += 50;

  printf("%u\n", num); /* Yes, this *might* print what you want */

  /* But this "if" almost certainly won't do what you want. */
  if(num > 0) {
    printf("Big numbers are big\n");
  } else {
    printf("Big numbers are small\n");
  }
} 

Мы используем «unsigned», поскольку unsigned int ведет себя не так, как int.Есть более интересные варианты поведения, чем просто printf.

0 голосов
/ 11 мая 2011

Ну, во-первых, результат присвоения номера вне диапазона определяется реализацией - ему не нужно давать значение, которое будет «работать» при печати со спецификатором формата %u.Но чтобы действительно ответить на ваш вопрос, рассмотрите следующую модификацию вашего кода:

#include <stdio.h>

int main(void)
{
    int num = 2147483650;
    unsigned num2 = 2147483650;

    num /= 2;
    num2 /= 2;

    printf("%u, %u\n" , num, num2);

    return 0;
}

(Если 2147483650 выходит за пределы int на вашей платформе, но в пределах диапазона unsigned, то вы будететолько правильный ответ 1073741825, используя тип unsigned.

0 голосов
/ 10 мая 2011
  1. Неверно.Диапазон составляет от INT_MIN (который в двух системах дополнения обычно составляет -INT_MAX + 1) до INT_MAX;INT_MAX и INT_MIN зависят от компилятора, архитектуры и т. Д.

  2. Неверно.Диапазон от 0 до UINT_MAX, обычно INT_MAX * 2 + 1

  3. Беззнаковые целые имеют другое поведение в отношении переполнения и семантики.В дополнении 2 есть одно значение, неопределенное для целых чисел со знаком (то есть, если установлен только самый верхний бит, остальные ноль), которое имеет некоторое двойное значение.Целые числа без знака могут использовать весь диапазон битовых комбинаций.

  4. Вот упражнение: на 32-битной машине сравните вывод printf ("% d% u", 0xffffffff, 0xffffffff);

  5. Поскольку целые числа без знака ведут себя иначе, чем целые числа со знаком.

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