"%ul"
означает "%u"
(беззнаковое целое) следует буква "l"
. Возможно, вы намеревались "%lu"
(без знака long), однако оба из них неверны для uint64_t
.
Собственный спецификатор находится в inttypes.h
, и это "%" PRIu64
.
Также это не печатает 0x
, как вы предложили, оно печатает десятичное представление. Используйте "%" PRIx64
для шестнадцатеричного представления (которое также не печатает ведущие 0x
).
Продолжая, ваш код вызывает undefined behaviour. Согласно правилу строгого псевдонима, не разрешается использовать выражение типа uint64_t
для доступа к любой переменной, которая не была записана как uint64_t
или int64_t
.
Вы можете избежать строгого правила наложения спектров, используя переменную нужного типа, либо в союзе или иным образом, например:
uint64_t x;
memcpy(&x, a, sizeof x);
printf("%" PRIu64 "\n", x);
Ваш компилятор оптимизирует это, так что не беспокойтесь о том, что является неэффективным или что-то.
Обратите внимание, что результат этого равен . Реализация определена, поскольку компилятор мог выбрать различные способы упорядочения бит uint64_t
. Два общих заказа: big-endian и малоэтажный.
Другая часть вашего вопроса касается других целочисленных типов. К сожалению, вы застряли в том, что предоставил ваш компилятор. Скорее всего, он не предлагал uint94_t
. Вам нужно будет перевернуть свой собственный код, чтобы достичь того, чего вы хотите. Например, вы можете имитировать 96-битовую большой Endian:
uint8_t a[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C};
uint64_t x = 0, y = 0;
mempcy((unsigned char *)&x + 4, a, 4);
memcpy(&y, a+4, 8);
printf("%" PRIx64 "%" PRIx64 "\n", x, y);
Конечно, вы могли бы просто напечатать его посимвольно.
примечание: это приводит к неопределенному поведению, также маловероятно, что он выдает выход на 96 бит, попробуйте сделать 'a' 12 байтами, как в моем последнем примере –