出于某种测试目的,我想显示int8_t变量,将其转换为uint8_t并再次以十六进制显示。
#include <iostream>
#include <sstream>
int main()
{
std::int8_t t = -1;
std::cout << std::hex << +t << std::endl;
std::cout << std::hex << +static_cast<std::uint8_t>(t) << std::endl;
return 0;
}
这是该程序的输出:
$ ./a.exe
ffffffff
ff
cout似乎将int8_t格式化为4个字节。这是为什么?因为它是一个字节的值,所以人们希望看到ff,就像uint8_t一样,在此示例中就是这种情况。
答案 0 :(得分:7)
为什么int8_t的输出格式使用4个字节?
不是。您正在输出int
,而不是int8_t
。
要通过词汇转换将uint8_t
传输到std::cout
,您已正确使用+
触发了对int
的升级(这是因为char
和相关类型不会通过IOstream进行词法转换。
但是随后……您已经将其提升为int
。因此,您会看到类似int
的事物。
您的第二行很不错,可以确保您不会碰到标志扩展名。
答案 1 :(得分:4)
问题是您使用执行整数提升的一元算术运算符+
。因此,您的int8_t
被提升为整数。使用您的编译器进行设置的是32位。
内置的一元加运算符返回其操作数的值。它不是空操作的唯一情况是操作数具有整数类型或无作用域枚举类型(通过整数提升来更改),例如,它将
char
转换为int
或如果操作数为接受左值到右值,数组到指针或函数到指针的转换。
一元+运算符的操作数应具有算术,无作用域枚举或指针类型,并且结果是自变量的值。积分提升是对整数或枚举操作数执行的。结果的类型就是提升的操作数的类型。
来源https://en.cppreference.com/w/cpp/language/operator_arithmetic§8.3.1.7
答案 2 :(得分:1)
对现有答案的补充
auto x1 = static_cast<int8_t>(-1);
// x1 has type int8_t and contains value -1
auto x2 = static_cast<uint8_t>(-1);
// x2 has type uint8_t and contains value 255 !
// uint8_t cant represent value -1
// promotion to int
auto y1 = +x1; // y1 has type int with value -1
auto y2 = +x2; // y2 has also type int with value 255
std::cout << y1 << "\n"; // output "-1"
std::cout << y2 << "\n"; // output "255"
std::cout << std::hex << y1 << "\n"; // output "ffffffff" for hex representation of -1
std::cout << std::hex << y2 << "\n"; // output "ff" for hex representation of 255
我希望这段代码片段可以使我更容易理解。