【问题标题】:Implicit conversion from uint8_t to int gone wrong, when explicit one gone well当显式转换顺利时,从 uint8_t 到 int 的隐式转换出错
【发布时间】:2019-11-02 07:26:40
【问题描述】:

我有一个程序,它获取数字 n(块的数量)和 r(体积),然后以 firstsize secondsize thirdsize(例如 1 1 1)格式获取 n 个大小,因此总体上最简单的输入是: 1 1 1 1 1 理论上应该返回 1。但事实并非如此。

我有以下代码:


#include <iostream>
#include <cstdint>
#include <vector>

using namespace std;

struct Size{
    long long w=0,h=0,d=0;
};
istream& operator>>(istream& istr, Size& rval){
    istr >> rval.w >> rval.h >> rval.d;
    return istr;
}


long long calcMass(Size s, int r){
    long long res = s.d*s.h*s.w*r;

    cout << "Gained:" << res << '\n';
    cout << "Got: sizes:{" << s.d << ' ' << s.h << ' ' << s.w << "}, p = " << r << '\n';
    return res;
}


int main(){
    int n;
    long long sum = 0;

    Size s;
    uint8_t r; // Condition is that r<100

    cin >> n >> r;

    for(int i=0; i<n; i++){
        cin >> s;
        sum += calcMass(s,r);
    }
    cout << sum;

}

实际上,我通过将main() 中的r 变量的类型从uint8_t 更改为int 解决了这个问题,但问题是,我不明白为什么它在uint8_t 时不起作用。当我尝试以下代码时:

    cout <<'\n' << static_cast<long long>(static_cast<int>((static_cast<uint8_t>(1))));

它给了我 1。

所以,我决定在main() 中使用uint8_t r 检查情况。 uint8_t r = 1 in main() 不知何故变成了 int r = 49 in calcMass() 我不明白为什么。

我知道隐式转换的规则,在小于int的操作变量转换为int之前,然后将“较小的”变量转换为较大的变量(例如int rlong longcalcMass(Size,int) 函数?),但我不明白的事情:为什么uint8_t r = 1 变成int r = 49

另外,我尝试将calcMass()r 的类型从int 更改为uint8_t。按理说,main() 中的uint8_t r = 1 变成了calcMass() 中的uint8_t r = 1,但是这个函数的结果还是49

这些是我用来运行程序的:

Operating System: Windows 10 Enterprise LTSC
System Type: 64bit
C++ compiler: MinGW

如果有人能解释 为什么uint8_t 显式转换为 long long 不等于将其传递给 calcMass() 并使用 @987654357 进行操作时,我会很高兴@使用它。

【问题讨论】:

  • 49 是 '1' 的 ASCII 码。因此,请查看 unsigned char 的方向以了解为什么您会得到 49。

标签: c++ type-conversion long-integer implicit-conversion uint8t


【解决方案1】:

恕我直言,OP 怀疑隐式与显式转换问题,但这不是原因。相反,必须调查stream I/O 操作符。

细化comment of S.M.

49 是 '1' 的 ASCII 码。因此,请查看 unsigned char 的方向以了解为什么您会得到 49。

std::stream 运算符对于 charsigned charunsigned charoperator<<(std::basic_ostream)operator>>(std::basic_istream))与其他整数类型(std::basic_ostream::operator<<std::basic_istream::operator>>)的工作方式略有不同.

这是输入和输出。

std::cout &lt;&lt; (int)49; 打印 49std::cout &lt;&lt; (char)49; 打印 1

std::uint8_t 很可能是typedef unsigned char uint8_t;
(SO: Implementation of fixed width integer types std::uint8_t and std::int8_t, C++)

示例:

#include <iostream>
#include <sstream>
#include <cstdint>

int main()
{
  std::cout << "(int)49: " << (int)49 << "\n";
  std::cout << "(char)49: " << (char)49 << "\n";
  std::cout << "(std::uint8_t)49: " << (std::uint8_t)49 << "\n";
  int i; char c; std::uint8_t u8;
  std::istringstream in("49\n1\n1");
  in >> i >> c >> u8;
  std::cout << "i: " << i << '\n';
  std::cout << "(int)c: " << (int)c << '\n';
  std::cout << "(int)u8: " << (int)u8 << '\n';
}

输出:

(int)49: 49
(char)49: 1
(std::uint8_t)49: 1
i: 49
(int)c: 49
(int)u8: 49

Live Demo on coliru

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 2022-01-22
    • 2013-05-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2018-11-24
    相关资源
    最近更新 更多