为什么固定宽度的整数打印出字符而不是整数?
Why do fixed-width integers print out chars instead of ints?
给定以下代码。
#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 位定宽整数上?这是编译器行为吗?
好吧,从某种意义上说,它们是整数,您可以用它们进行 8 位整数运算。
但显然在您的系统上,int8_t
被实现为 typedef
到 signed char
。这是完全合法的,因为 signed char
s 也是整数,但给出了意想不到的结果,因为 signed char
s 的 operator<<
打印了它们的字符符号而不是它们的数值。如果有人试图打印 signed char
.
,其他任何事情都会很奇怪
如果您想查看 int8_t
的数值,只需在打印前转换为 int
。
(可选的)固定宽度类型 intN_t
,以及各种其他类型,如 uint_fast16_t
、uintmax_t
和 intptr_t
,是 别名 用于其中一种内置整数类型。您不知道它们别名的实际类型是什么,只知道它们必须满足记录的约束。
在 "exactly 8 bits" 的情况下,约束没有留下太多空间,但是,唯一可以是 8 位宽的整数类型是 char
类型(回想一下有 3 个其中)。因此 int8_t
,如果存在,则必须是 char
或 signed char
.
的别名
无关地,iostreams 为所有字符类型定义了 operator<<
的重载,这些字符类型具有将值直接写入输出的效果,而不是将整数格式化为十进制字符串(这样您就可以方便地写 std::cout << 'a'
),并且此重载也用于 int8_t
—— 重载解析适用于类型,而不适用于类型名称。 (可能令人遗憾的是,有一个 special ostream overload for signed char
;如果 仅 为 char
提供重载并像普通整数一样对待其他类型可能会更好。 ) 这就是为什么您会在系统编码中看到打印为字符的值。
如果要打印格式化为字符串的值,只需将其转换为更广泛的整数类型之一。例如,您可以使用一元加号应用标准促销:int8_t x = 5; std::cout << +x;
给定以下代码。
#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 位定宽整数上?这是编译器行为吗?
好吧,从某种意义上说,它们是整数,您可以用它们进行 8 位整数运算。
但显然在您的系统上,int8_t
被实现为 typedef
到 signed char
。这是完全合法的,因为 signed char
s 也是整数,但给出了意想不到的结果,因为 signed char
s 的 operator<<
打印了它们的字符符号而不是它们的数值。如果有人试图打印 signed char
.
如果您想查看 int8_t
的数值,只需在打印前转换为 int
。
(可选的)固定宽度类型 intN_t
,以及各种其他类型,如 uint_fast16_t
、uintmax_t
和 intptr_t
,是 别名 用于其中一种内置整数类型。您不知道它们别名的实际类型是什么,只知道它们必须满足记录的约束。
在 "exactly 8 bits" 的情况下,约束没有留下太多空间,但是,唯一可以是 8 位宽的整数类型是 char
类型(回想一下有 3 个其中)。因此 int8_t
,如果存在,则必须是 char
或 signed char
.
无关地,iostreams 为所有字符类型定义了 operator<<
的重载,这些字符类型具有将值直接写入输出的效果,而不是将整数格式化为十进制字符串(这样您就可以方便地写 std::cout << 'a'
),并且此重载也用于 int8_t
—— 重载解析适用于类型,而不适用于类型名称。 (可能令人遗憾的是,有一个 special ostream overload for signed char
;如果 仅 为 char
提供重载并像普通整数一样对待其他类型可能会更好。 ) 这就是为什么您会在系统编码中看到打印为字符的值。
如果要打印格式化为字符串的值,只需将其转换为更广泛的整数类型之一。例如,您可以使用一元加号应用标准促销:int8_t x = 5; std::cout << +x;