从 uint8_t 到 int 的隐式转换出错了,当显式转换进展顺利时

Implicit conversion from uint8_t to int gone wrong, when explicit one gone well

本文关键字:转换 换进 错了 换出 int uint8      更新时间:2023-10-16

>我有一个程序,它得到数字n(块的数量)和r(体积),之后它得到n个大小的格式firstsize secondsize thirdsize(例如1 1 1),所以总体最简单的输入是: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 = 1main()不知何故成为calcMass()int r = 49,我不明白为什么。

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

另外,我尝试将calcMass()中的r类型从int更改为uint8_t。如前所述,main()中的uint8_t r = 1calcMass()中变为uint8_t r = 1,但这个函数的结果仍然是49

这些我用来运行程序:

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

如果有人能解释为什么在将uint8_t传递给calcMass()并使用long long进行操作时,将显式转换为long long不等于 imlpicit 不等于 imlpicit 。

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

阐述S.M.的评论:

49 是 ASCII 代码"1"。因此,请看向无符号字符的方向,以了解为什么您会得到 49。

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

这既用于输入,也用于输出。

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

std::uint8_t很可能是一个typedef unsigned char uint8_t;.
(SO:固定宽度整数类型 std::uint8_t 和 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("49n1n1");
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

科里鲁的现场演示