pixel_data
- это вектор
из char
.
Когда я выполняю printf ("0x% 1x", pixel_data [0])
, я ожидаю увидеть 0xf5
.
Но я получаю 0xfffffff5
, как будто я распечатываю 4-байтовое целое вместо 1 байта.
Почему это? Я дал printf
char
для печати - это всего лишь 1 байт, так почему же printf
печатает 4?
NB. реализация printf
заключена в сторонний API, но просто интересно, является ли это функцией стандартного printf
?
Вы, вероятно, получаете доброкачественную форму неопределенного поведения, потому что модификатор % x
ожидает ] unsigned int
параметр и char
обычно будут преобразованы в int
при передаче в функцию varargs .
Вы должны явно преобразовать char в unsigned int
, чтобы получить предсказуемые результаты:
printf(" 0x%1x ", (unsigned)pixel_data[0] );
Обратите внимание, что ширина поля , равная единице, не очень полезна. Он просто указывает минимальное количество отображаемых цифр, и в любом случае потребуется хотя бы одна цифра.
Если char
на вашей платформе подписан, то это преобразование преобразует отрицательные значения char
в большие беззнаковые int
значения (например, fffffff5
). Если вы хотите обрабатывать байтовые значения как беззнаковые значения и просто расширять ноль при преобразовании в unsigned int
, вы должны использовать unsigned char
для pixel_data
или преобразовать через ] unsigned char
или используйте операцию маскирования после повышения.
например.
printf(" 0x%x ", (unsigned)(unsigned char)pixel_data[0] );
или
printf(" 0x%x ", (unsigned)pixel_data[0] & 0xffU );
Спецификатор ширины в printf
на самом деле является min-width. Вы можете выполнить printf ("0x% 2x", pixel_data [0] & 0xff)
, чтобы напечатать младший байт (примечание 2, чтобы напечатать два символа, если pixel_data [0]
, например, 0xffffff02
).
Лучше использовать флаги стандартного формата
printf(" %#1x ", pixel_data[0] );
, тогда компилятор поставит шестнадцатеричный префикс за вас.