Передача unsigned long long в параметр char в C

Я смотрю на следующий код:

#include <stdio.h>
#include <limits.h>

bool
writebytes (unsigned long long x, int nbytes)
{
  do
    {
      if (putchar (x) < 0)
        return false;
      x >>= CHAR_BIT;
      nbytes--;
    }
  while (0 < nbytes);

  return true;
}

И это работает (написано моим профессором).

Я понимаю, что он выводит все nbytes из unsigned long long x на экран, и как он это делает. Мой единственный вопрос: почему в C вы можете передать unsigned long long функции, которая принимает char в качестве параметра putchar(int char), и она все равно интерпретирует его правильно?

Захватывает ли C только первый CHAR_BIT переданного параметра? Почему нет необходимости в кастинге, например:

Putchar( (char) x )

Я не верю, что этот код гарантированно сработает. Он может работать на определенной платформе, с определенным компилятором и библиотеками, но это плохое основание для того, чтобы считать что-то "правильным".

Tom Karzes 23.02.2023 03:34
putchar() принимает int, а не char. Однако применяются те же правила преобразования.
Shawn 23.02.2023 03:36

(что, если я правильно понял, преобразование большего целочисленного типа в меньший тип со знаком определяется реализацией, если только преобразуемое значение уже не вписывается в диапазон меньшего типа. Внутренне putchar() преобразует свой аргумент int в беззнаковый char, который хорошо определен, но переход от unsigned long long к int first не является)

Shawn 23.02.2023 03:45

Неявное преобразование unsigned long long в int может привести к переполнению (т. е. если оно не может быть представлено новым типом). Я считаю, что поведение, когда это происходит, определяется реализацией и может привести к поднятию сигнала.

Tom Karzes 23.02.2023 03:53
Калькулятор CGPA 12 для семестра
Калькулятор CGPA 12 для семестра
Чтобы запустить этот код и рассчитать CGPA, необходимо сохранить код как HTML-файл, а затем открыть его в веб-браузере. Для этого выполните следующие...
Как собрать/развернуть часть вашего приложения Angular
Как собрать/развернуть часть вашего приложения Angular
Вам когда-нибудь требовалось собрать/развернуть только часть вашего приложения Angular или, возможно, скрыть некоторые маршруты в определенных средах?
Запуск PHP на IIS без использования программы установки веб-платформы
Запуск PHP на IIS без использования программы установки веб-платформы
Установщик веб-платформы, предлагаемый компанией Microsoft, перестанет работать 31 декабря 2022 года. Его закрытие привело к тому, что мы не можем...
Оптимизация React Context шаг за шагом в 4 примерах
Оптимизация React Context шаг за шагом в 4 примерах
При использовании компонентов React в сочетании с Context вы можете оптимизировать рендеринг, обернув ваш компонент React в React.memo сразу после...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Настройка шаблона Metronic с помощью Webpack и Gulp
Настройка шаблона Metronic с помощью Webpack и Gulp
Я пишу эту статью, чтобы поделиться тем, как настроить макет Metronic с помощью Sass, поскольку Metronic предоставляет так много документации, и они...
3
4
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
putchar(int char)

Параметр putchar является int. Типа нет int char.

В putchar(x) unsigned long long x преобразуется в тип параметра int согласно C 2018 6.5.2.2 7. Если значение x не может быть представлено в типе int, результатом является значение или сигнал, определяемый реализацией, согласно C 2018 6.3. .1.3 3. Обычные современные реализации C переносят значение по модулю INT_MAX+1, что эквивалентно взятию младших n байтов, если используется дополнение до двух, где n — количество байтов в int.

C 2018 7.21.7.8, 7.21.7.7 и 7.21.7.3 указано, что putchar записывает символ, указанный путем преобразования его параметра в unsigned char. Это преобразование перенесет значение по модулю UCHAR_MAX+1, что эквивалентно взятию младшего байта.

Таким образом, в большинстве современных реализаций C putchar(x) будет записывать младший байт x в стандартный вывод.

Затем x >>= CHAR_BIT; сдвигает байты в x на один байт вниз, и цикл повторяется, чтобы записать nbytes байт.

Изменение putchar (x) на putchar((unsigned char) x) улучшит переносимость за счет удаления определяемого реализацией преобразования в int.

Другие вопросы по теме