eConti - программирование в вопросах и ответах

как напечатать f 0x0000000 вместо (nil) и 0x08ffffff вместо 0x8ffffff в c

Я пытаюсь использовать stdout stream для печати 0x00000000 вместо (nil) и 0x08ffffff вместо 0x8ffffff.

В общем, char *ptr1 = 0x00000000 и char *ptr2 = 0x08ffffff.

Когда я бегу

printf("start of address is %p and end of address is %p", ptr1, ptr2);

я получил

start of address is (nil) and end of address is 0x8ffffff

Я действительно нашел способ обойти это, и я действительно сделал бы это:

char *ptr1 = 0x00000000; 
char *ptr2 = 0x08ffffff;
printf("start 0x%08x and end 0x%08x\n",ptr1, ptr2);

Это генерирует

start 0x00000000 and end 0x08ffffff

Однако компилятор отправляет следующее предупреждение:

warning: format ‘%x’ expects argument of type ‘unsigned int’, 
but argument 3 has type ‘void *’ [-Wformat=]

Как мне изменить printf, чтобы настроить вывод на печать?

02.02.2021

  • Приведите его к uintptr_t и распечатайте, как описано в stackoverflow.com/questions/5795978/ 02.02.2021
  • @WilliamPursell Очень плохая идея, поскольку 64-битные среды становятся все более распространенными. 02.02.2021
  • @WilliamPursell я получаю эту ошибку error: ‘uint32_t’ undeclared (first use in this function) printf("%08x - %08x RW\n",(uint32_t)regions[i].from,(uint32_t)regions[i].to); 02.02.2021
  • @Hadi Если есть шанс, что вы скомпилируете этот код в 64-битной среде, вы все равно не захотите использовать uint32_t таким образом. 02.02.2021

Ответы:


1

Во-первых, чтобы контролировать способ печати адресов, вы должны преобразовать их в целочисленный тип. Спецификации для печати указателей с %p неадекватны. Для этого можно включить <stdint.h> и использовать тип uintptr_t, который представляет собой целочисленный тип без знака, подходящий для некоторой работы с адресами.

Во-вторых, заголовок <inttypes.h> предоставляет макрос PRIxPTR, который предоставляет спецификатор преобразования printf для печати uintptr_t значений в шестнадцатеричном виде.

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

Вот пример кода:

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>

static void PrintAddress(const void *p)
{
    uintptr_t u = (uintptr_t) p;
    printf("0x%08" PRIxPTR, u);
}

int main(void)
{
    char *ptr1 = (char *) 0x00000000;
    char *ptr2 = (char *) 0x08ffffff;
    printf("Start of address is ");
    PrintAddress(ptr1);
    printf(" and end of address is ");
    PrintAddress(ptr2);
    printf(".\n");
}

Более того, вы можете адаптировать ширину поля к размеру uintptr_t в вашей реализации C, включив <limits.h> и рассчитав необходимое количество цифр:

    printf("0x%0*" PRIxPTR, ((int) sizeof u * CHAR_BIT + 3) / 4, u);

Обратите внимание, что прямая установка указателей на жестко закодированные постоянные значения, как вы делаете с инициализациями ptr1 и ptr2, встречается редко. Обычно он используется при выполнении специальных операций с оборудованием. Когда вы намеренно конвертируете целое число в указатель, вы должны использовать приведение, чтобы избежать предупреждения компилятора.

02.02.2021
  • как насчет (sizeof u * CHAR_BIT + 3) / 4, чтобы он работал на моем компьютере с 9-битным символом / 18-битным адресом :-P 02.02.2021
  • @AntiHaapala: Хорошо. 02.02.2021
  • обратите внимание, что соответствующая система может не поддерживать uintptr_t . В этом случае мы можем перебирать байты числа (полученного любым желаемым методом), печатая два кусочка за раз 02.02.2021
  • @M.M: Ну, я бы написал для этого код, но для его поддержки и реализации не-8 CHAR_BIT нам пришлось бы написать код, который обрабатывает шестнадцатеричные цифры, разделенные по «байтам» реализации, т. Е. Поддерживать буфер сдвига битов . Или иным образом разместить байты нечетного размера. Я думаю, что не буду заходить так далеко прямо сейчас. 02.02.2021
  • Новые материалы

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

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

    Будущее сельского хозяйства: новый уровень производительности с современными технологиями
    По мере роста населения мира растет и спрос на продукты питания. Фермеры сталкиваются с растущим давлением необходимости повышать урожайность и максимизировать производительность, манипулируя..

    Состояние совместной фильтрации в 2022 году, часть 1
    ResBeMF: Улучшение прогнозируемого охвата совместной фильтрации на основе классификации (arXiv) Автор: Анхель Гонсалес-Прието , Авраам Гутьеррес , Фернандо Ортега , Рауль Лара-Кабрера..

    Зачем изучать PYTHON в 2022 году !
    Python — востребованный, доступный язык программирования с активным, постоянно растущим сообществом пользователей. Для тех, кто хочет сменить профессию в мире технологий с помощью..

    Решение капч с помощью Puppeteer
    Это руководство предназначено для текстовых кодов, а не для reCAPTCHA Google (см. конец этого сообщения). Требования: Антикапча или любой другой сервис по разгадыванию капчи. Модуль..

    7 встроенных библиотек Python, которые необходимо знать
    7 встроенных библиотек Python, которые необходимо знать Стандартная библиотека Python значительно упрощает жизнь программистов, предоставляя широкий набор функций. Мы выбираем несколько..