%#08XПреобразование должно предшествовать значение с 0X; это требуется стандартом. В стандарте нет никаких доказательств того, что они #должны изменять поведение 08части спецификации, за исключением того, что 0Xпрефикс считается частью длины (так что вы можете / должны использовать %#010X. Если, как и я, вам нравится ваш гекс, представленный как 0x1234CDEF, затем вы должны использовать 0x%08Xдля достижения желаемого результата. Вы можете использовать, %#.8Xи это также должно вставить ведущие нули.
Попробуйте варианты в следующем коде:
#include <stdio.h>
int main(void)
{
int j = 0;
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
for (int i = 0; i < 8; i++)
{
j = (j << 4) | (i + 6);
printf("0x%.8X = %#08X = %#.8X = %#010x\n", j, j, j, j);
}
return(0);
}
На машине с RHEL 5, а также на Mac OS X (10.7.5) вывод был:
0x00000000 = 00000000 = 00000000 = 0000000000
0x00000006 = 0X000006 = 0X00000006 = 0x00000006
0x00000067 = 0X000067 = 0X00000067 = 0x00000067
0x00000678 = 0X000678 = 0X00000678 = 0x00000678
0x00006789 = 0X006789 = 0X00006789 = 0x00006789
0x0006789A = 0X06789A = 0X0006789A = 0x0006789a
0x006789AB = 0X6789AB = 0X006789AB = 0x006789ab
0x06789ABC = 0X6789ABC = 0X06789ABC = 0x06789abc
0x6789ABCD = 0X6789ABCD = 0X6789ABCD = 0x6789abcd
Я немного удивлен лечением 0; Я не понимаю, почему 0Xпрефикс пропущен, но с двумя отдельными системами это должно быть стандартным. Это подтверждает мои предубеждения против #варианта.
Обработка нуля в соответствии со стандартом.
Characters6 Символы флага и их значения:
...
#Результат преобразуется в «альтернативную форму». ... Для x(или X) преобразования ненулевой результат имеет 0x(или 0X) префикс к нему. ...
(Акцент добавлен.)
Обратите внимание, что при использовании %#Xбудут использоваться заглавные буквы для шестнадцатеричных цифр и 0Xв качестве префикса; Использование %#xбудет использовать строчные буквы для шестнадцатеричных цифр и 0xв качестве префикса. Если вы предпочитаете в 0xкачестве префикса и прописных букв, вы должны коде 0xотдельно: 0x%X. Разумеется, при необходимости можно добавлять другие модификаторы формата.
Для печати адресов используйте <inttypes.h>заголовок, uintptr_tтип и PRIXPTRмакрос формата:
#include <inttypes.h>
#include <stdio.h>
int main(void)
{
void *address = &address; // &address has type void ** but it converts to void *
printf("Address 0x%.12" PRIXPTR "\n", (uintptr_t)address);
return 0;
}
Пример вывода:
Address 0x7FFEE5B29428
Выбери свой яд по длине - я считаю, что точность 12 хорошо работает для адресов на Mac под управлением macOS. В сочетании с .указанием минимальной точности (цифр) он надежно форматирует адреса. Если вы установите точность до 16, дополнительные 4 цифры всегда будут равны 0 в моем опыте на Mac, но, безусловно, есть смысл использовать 16 вместо 12 в переносимом 64-битном коде (но вы бы использовали 8 для 32-битный код).
0x%.8X? Это будет приводить заполняются нулями. (0xэто просто преамбула, но вы, вероятно, уже знаете об этом).