从 uint8_t 到 int 的隐式转换出错了,当显式转换进展顺利时
Implicit conversion from uint8_t to int gone wrong, when explicit one gone well
>我有一个程序,它得到数字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 = 1
main()
不知何故成为calcMass()
的int r = 49
,我不明白为什么。
我知道隐式转换的规则,在将小于int
的操作变量转换为int
之前,然后将"较小大小"的变量转换为较大的变量(例如int r
long long
calcMass(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
传递给calcMass()
并使用long long
进行操作时,将显式转换为long long
不等于 imlpicit 不等于 imlpicit 。
恕我直言,OP 怀疑隐式与显式转换问题,但这不是原因。相反,必须调查 I/O 运算符stream
。
阐述S.M.的评论:
49 是 ASCII 代码"1"。因此,请看向无符号字符的方向,以了解为什么您会得到 49。
std::stream
运算符对于char
、signed char
和unsigned char
(operator<<(std::basic_ostream),operator>>(std::basic_istream))的工作方式与其他整数类型(std::basic_ostream::operator<<,std::basic_istream::operator>>)略有不同。
这既用于输入,也用于输出。
std::cout << (int)49;
打印49
但std::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
科里鲁的现场演示
- 如何将包含epoch时间的十六进制字符串转换为time_t
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 为什么mpfr_printf与十六进制浮点(%a转换说明符)的printf不同
- 用c++把小数点转换成八进制
- 如何在C++中将十六进制字符串转换为文本数据
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 使用 sprintf 将十六进制0xAABBCC转换为字符串"AA:BB:CC"
- 如何将带有十六进制值的 std::string 转换为 std::vector<无符号字符>
- 将字符串(可以是十进制字符串或十六进制字符串)转换为整数C++
- 在Arduino中将字符串转换为(逗号分隔的十六进制)字符串到无符号字符数组
- 将 std::string( "x3BxDEx7C" ) 转换为可读的十六进制字符串?
- 将十六进制转换为 DEC
- C++ 将十六进制字符串表示形式转换为十六进制字符串表示形式
- 字符数组到十六进制字符串的转换 - 意外输出
- C++将 wwn 字符串转换为识别为十六进制的数据类型
- 将字符串存储为十六进制而不进行转换
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 将字符串转换为十六进制数组c++
- 十六进制到十进制转换的未清理答案