【问题标题】:Why do fixed-width integers print out chars instead of ints?为什么固定宽度的整数打印出字符而不是整数?
【发布时间】:2015-05-25 23:18:11
【问题描述】:

给定以下代码。

#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 位固定宽度整数上?这是编译器行为吗?

【问题讨论】:

  • std::is_same&lt;std::int8_t, signed char&gt;::value

标签: c++ integer fixed-width


【解决方案1】:

嗯,从某种意义上说,它们是整数,您可以用它们进行 8 位整数运算。

但显然在您的系统上,int8_t 被实现为 typedefsigned char。这是完全合法的,因为signed chars 也是整数,但是由于operator&lt;&lt;signed chars 打印的是它们的字符符号而不是它们的数值,所以会产生意想不到的结果。如果有人试图打印signed char,其他任何事情都会很奇怪。

如果您想查看int8_t 的数值,只需在打印前转换为int

【讨论】:

  • 感谢您的回答。这是他们对int8_t 所做的一件棘手的事情。
  • 我希望存在不透明的 typedef... :(
【解决方案2】:

(可选)固定宽度类型intN_t,以及各种其他类型,如uint_fast16_tuintmax_tintptr_t,是内置积分之一的别名类型。您不知道它们别名的实际类型是什么,只知道它们必须满足记录的约束。

在“正好 8 位”的情况下,约束不会留下太多空间,并且唯一可以为 8 位宽的整数类型是 char 类型(回想一下,其中有三个)。所以int8_t,如果存在,必须是charsigned char 的别名。

不相关的是,iostreams 为所有字符类型定义了 operator&lt;&lt; 的重载,其效果是将值直接写入输出,而不是将整数格式化为十进制字符串(这样您就可以方便地编写 std::cout &lt;&lt; 'a' ),并且此重载也用于int8_t - 重载解析适用于类型,而不适用于类型名称。 (有一个 special ostream overload for signed char 可能令人遗憾; 提供 char 的重载并将其他类型视为普通整数可能会更好。)这就是为什么您会看到该值打印为系统编码中的字符。

如果您想打印格式化为字符串的值,只需将其转换为更广泛的整数类型之一。例如,您可以应用带有一元加号的标准促销:int8_t x = 5; std::cout &lt;&lt; +x;

【讨论】:

  • 它们真的必须是“内置”整数类型的别名吗?
  • @MSalters:是的。相关措辞在 C 标准中,该库组件是从该标准中导入的。术语“有符号整数类型”是一个艺术术语,在“语言/概念/类型”中定义。
  • @Kerrek SB 我从未听说过使用 +x 将输出中的字符更改为整数。我认为这只是一个冗余的一元运算符,它明确表示一个值为正数?
  • @WanderingIdiot:C++ 类型系统非常复杂。 Default promotions and arithmetic conversions 不可掉以轻心:-S
  • @WanderingIdiot 算术运算符都会在运算前将任何小于int 的整数类型提升为int
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2022-01-02
  • 1970-01-01
  • 2016-07-24
相关资源
最近更新 更多