Единственный переносимый способ печати значений указателя - это использование спецификатора "%p"
, который создает выходные данные, определяемые реализацией. (Преобразование в uintptr_t
и использование PRIxPTR
, вероятно, сработает, но (a) uintptr_t
было введено в C99, поэтому некоторые компиляторы могут не поддерживать его, и (b) он не гарантированно существует даже в C99 (там может не быть целочисленным типом, достаточно большим, чтобы вместить все возможные значения указателя.
Поэтому используйте "%p"
с sprintf()
(или snprintf()
, если он у вас есть), чтобы напечатать строку, а затем напечатать заполнение строки начальными пробелами.
Одна проблема заключается в том, что нет действительно хорошего способа определить максимальную длину строки, получаемой с помощью "%p"
.
Это, по общему признанию, неудобно (хотя, конечно, вы можете обернуть его в функцию). Если вам не нужна 100% переносимость, я никогда не использовал систему, которая приводила бы указатель к unsigned long
и печать результата с использованием "0x%16lx"
не работала бы. [ ОБНОВЛЕНИЕ : Да, у меня есть. 64-битная Windows имеет 64-битные указатели и 32-битные unsigned long
.] (Или вы можете использовать "0x%*lx"
и вычислить ширину, возможно, что-то вроде sizeof (void*) * 2
. Если вы действительно параноик, вы можете учитывать системы где CHAR_BIT > 8
, так что вы получите более 2 шестнадцатеричных цифр на байт.)