为什么 int8_t 和用户通过 cin 输入显示奇怪的结果

2022-01-14 00:00:00 int c++ uint8t

一小段代码让我发疯,但希望你能阻止我跳出窗口.看这里:

A tiny piece of code drives me crazy but hopefully you can prevent me from jumping out of the window. Look here:

#include <iostream>
#include <cstdint>

int main()
{
    int8_t i = 65;
    int8_t j;

    std::cout << "i = " << i << std::endl; // the 'A' is ok, same as uchar

    std::cout << "Now type in a value for j (use 65 again): " << std::endl;
    std::cin >> j;
    std::cout << "j = " << j << std::endl;

    if (i != j) 
        std::cout << "What is going on here?????" << std::endl;
    else 
        std::cout << "Everything ok." << std::endl;

    return 0;
}

如果我使用 int 而不是 int8_t 一切正常.我需要它作为 8 位 unsigned integers,而不是更大.顺便说一句.unsigned charint8_t 的行为相同.

If I use int instead of int8_t everything ok. I need this as 8-bit unsigned integers, not bigger. And btw. with unsigned char it's the same behaviour - of course - as with int8_t.

有人有提示吗?

推荐答案

int8_t 是一个整数类型的 typedef,具有所需的特性:纯 2 的补码表示,没有填充位,大小正好8 位.

int8_t is a typedef for an integer type with the required characteristics: pure 2's-complement representation, no padding bits, size of exactly 8 bits.

对于大多数(也许是所有)编译器,这意味着它将是 signed char 的 typedef.(因为术语 signed integer type,它不能是普通 char 的 typedef,即使 char 恰好被签名).

For most (perhaps all) compilers, that means it's going to be a typedef for signed char.(Because of a quirk in the definition of the term signed integer type, it cannot be a typedef for plain char, even if char happens to be signed).

>> 运算符对字符类型进行特殊处理.读取字符读取单个输入字符,而不是表示十进制整数值的字符序列.所以如果下一个输入字符是'0',那么读取的值就是character值'0',大概是48.

The >> operator treats character types specially. Reading a character reads a single input character, not sequence of characters representing some integer value in decimal. So if the next input character is '0', the value read will be the character value '0', which is probably 48.

由于 typedef 为现有类型创建别名,而不是新的不同类型,因此 >> 运算符无法知道您想要将 int8_t 视为整数类型而不是字符类型.

Since a typedef creates an alias for an existing type, not a new distinct type, there's no way for the >> operator to know that you want to treat int8_t as an integer type rather than as a character type.

问题在于,在大多数实现中,没有不是字符类型的 8 位整数类型.

The problem is that in most implementations there is no 8-bit integer type that's not a character type.

唯一的解决方法是读入 int 变量,然后转换为 int8_t(如果需要,可以进行范围检查).

The only workaround is to read into an int variable and then convert to int8_t (with range checks if you need them).

顺便说一下,int8_t 是一个 signed 类型;对应的无符号类型为uint8_t,范围为0..255.

Incidentally, int8_t is a signed type; the corresponding unsigned type is uint8_t, which has a range of 0..255.

(再考虑:如果标准允许的CHAR_BIT > 8,那么int8_tuint8_t都不会被定义完全没有.)

(One more consideration: if CHAR_BIT > 8, which is permitted by the standard, then neither int8_t nor uint8_t will be defined at all.)

相关文章