为什么固定宽度整数打印出字符而不是整数?

时间:2015-05-25 23:18:12

标签: c++ integer fixed-width

给出以下代码。

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

2 个答案:

答案 0 :(得分:12)

嗯,它们是整数,因为你可以用它们进行8位整数运算。

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

如果您想查看int8_t的数值,请在打印前投放到int

答案 1 :(得分:2)

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

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

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

如果要打印格式化为字符串的值,只需将其转换为更宽泛的整数类型之一。例如,您可以使用一元加号char

来应用标准促销