为什么固定宽度的整数输出的是字符而不是整型?

Why do fixed-width integers print out chars instead of ints?

本文关键字:整型 字符 整数 输出 为什么 固定宽度      更新时间:2023-10-16

给出以下代码:

#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被实现为typedefsigned char。这是完全合法的,因为signed char s也是整数,但是会产生意想不到的结果,因为signed char s的operator<<打印它们的字符符号而不是它们的数值。如果有人试图打印signed char,其他任何东西都会很奇怪。

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

(可选的)固定宽度类型intN_t,以及其他各种类型,如uint_fast16_t, uintmax_tintptr_t,都是一个内置整型的别名。您不知道它们混叠的实际类型是什么,只知道它们必须满足文档约束。

在"正好8位"的情况下,约束没有留下太多的空间,但是,唯一可以8位宽的整型是char类型(回想一下,有三个类型)。所以int8_t,如果存在的话,一定是charsigned char的别名。

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

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