给出以下代码。
#include <cstdint>
#include <iostream>
#include <limits>
int main()
{
int8_t x = 5;
std::cout << x << '\n';
int y = 5;
std::cout << y;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
return 0;
}
我的输出是三叶草和 5 。如果固定宽度整数是整数,为什么它们输出它们的数字的ASCII字符符号?
编辑:刚发现这种行为只发生在8位固定宽度的整数上?这是编译器的行为吗?
答案 0 :(得分:12)
嗯,它们是整数,因为你可以用它们进行8位整数运算。
但显然在您的系统上,int8_t
被实现为typedef
到signed char
。这是完全合法的,因为signed char
也是整数,但由于operator<<
signed char
打印其字符符号而不是其数字值,因此会产生意外结果。如果有人试图打印signed char
,那么其他任何事情都会很奇怪。
如果您想查看int8_t
的数值,请在打印前投放到int
。
答案 1 :(得分:2)
(可选)固定宽度类型intN_t
以及其他各种类型,例如uint_fast16_t
,uintmax_t
和intptr_t
,都是别名对于其中一个内置整数类型。您不知道它们的别名实际类型是什么,只是它们必须满足记录的约束。
在“正好8位”的情况下,约束不会留下太多空间,并且唯一可以是8位宽的整数类型是char
类型(回想其中有三种类型) )。因此int8_t
(如果存在)必须是char
或signed char
的别名。
不相关的是,iostreams为所有字符类型定义了operator<<
的重载,这些字符类型具有将值直接写入输出的效果,而不是将整数格式化为十进制字符串(这样您就可以方便地编写{ {1}}),此重载也用于std::cout << 'a'
- 重载解析适用于类型,而不适用于类型名称。 (或许遗憾的是有一个special ostream overload for signed char
;它可能更好只为int8_t
提供重载并将其他类型视为普通整数。)这就是为什么您会在系统的编码中看到作为字符打印的值。
如果要打印格式化为字符串的值,只需将其转换为更宽泛的整数类型之一。例如,您可以使用一元加号char