C++隐式转换(有符号 + 无符号)
C++ Implicit Conversion (Signed + Unsigned)
我知道,关于隐式转换,如果我们有一个无符号类型操作数和一个有符号类型操作数,并且无符号操作数的类型与有符号操作数的类型相同(或更大(,则有符号操作数将转换为无符号。
所以:
unsigned int u = 10;
signed int s = -8;
std::cout << s + u << std::endl;
//prints 2 because it will convert `s` to `unsigned int`, now `s` has the value
//4294967288, then it will add `u` to it, which is an out-of-range value, so,
//in my machine, `4294967298 % 4294967296 = 2`
我不明白的是 - 我读到如果有符号操作数的类型比无符号操作数大:
- 如果无符号类型
中的所有值都适合较大的类型,则无符号操作数将转换为有符号类型
如果无符号类型中的值不适合较大的类型,则有符号操作数将转换为无符号类型
所以在下面的代码中:
signed long long s = -8;
unsigned int u = 10;
std::cout << s + u << std::endl;
u
将转换为有符号长整型,因为 int 值可以容纳有符号长整型??
如果是这种情况,在什么情况下,较小的类型值不适合较大的类型值?
标准中的相关引用:
5 表达式 [expr]
10 许多期望算术操作数或运算数的二元运算符 枚举类型导致转换和产生结果类型类似 道路。目的是产生一个通用类型,这也是 结果。这种模式称为通常的算术转换, 定义如下:
[省略关于等号类型或等号类型的2条]
— 否则,如果具有无符号整数类型的操作数具有秩 大于或等于其他操作数类型的秩, 带符号整数类型的操作数应转换为 具有无符号整数类型的操作数。
— 否则,如果类型 具有有符号整数类型的操作数可以表示所有值 具有无符号整数类型的操作数类型,操作数 带无符号整数的类型应转换为 具有有符号整数类型的操作数。
— 否则,两个操作数都应是 转换为与 的类型对应的无符号整数类型 具有有符号整数类型的操作数。
让我们考虑以下 3 个示例案例,用于上述 3 个子句中的每一个,其中 sizeof(int) < sizeof(long) == sizeof(long long)
(易于适应其他情况(
#include <iostream>
signed int s1 = -4;
unsigned int u1 = 2;
signed long int s2 = -4;
unsigned int u2 = 2;
signed long long int s3 = -4;
unsigned long int u3 = 2;
int main()
{
std::cout << (s1 + u1) << "n"; // 4294967294
std::cout << (s2 + u2) << "n"; // -2
std::cout << (s3 + u3) << "n"; // 18446744073709551614
}
带输出的实时示例。
第一句:秩相等的类型,因此signed int
操作数转换为unsigned int
。这需要一种价值转换,该转换(使用二的补码(赋予印刷价值。
更高的等级,并且(在这个平台上!(可以表示无符号类型的所有值,所以无符号操作数被转换为有符号类型,你得到-2
第三句:有符号类型再次具有更高的秩,但(在这个平台上!(不能表示无符号类型的所有值,因此两个操作数都转换为unsigned long long
,并且在有符号操作数上进行值转换后,您将获得打印值。
请注意,当无符号操作数足够大(例如这些示例中为 6(时,由于无符号整数溢出,最终结果将为所有 3 个示例提供 2。
(已添加(请注意,当您对这些类型进行比较时,您会得到更多意外的结果。让我们考虑上面的例子 1 和 <
:
#include <iostream>
signed int s1 = -4;
unsigned int u1 = 2;
int main()
{
std::cout << (s1 < u1 ? "s1 < u1" : "s1 !< u1") << "n"; // "s1 !< u1"
std::cout << (-4 < 2u ? "-4 < 2u" : "-4 !< 2u") << "n"; // "-4 !< 2u"
}
由于2u
是由u
后缀明确unsigned
的,因此适用相同的规则。结果可能不是您在用 C++ -4 < 2u
编写时比较 -4 <2 时所期望的......
signed int
不适合unsigned long long
。因此,您将进行此转换: signed int
-> unsigned long long
.
请注意,C++11 标准在这里不讨论更大或更小的类型,它讨论的是等级较低或较高的类型。
考虑 long int
和 unsigned int
的情况,其中两者都是 32 位。long int
的秩比unsigned int
大,但由于long int
和unsigned int
都是32位的,long int
不能代表unsigned int
的所有值。
因此,我们陷入最后一种情况(C++11:5.6p9(:
- 否则,两个操作数都应转换为对应于 具有有符号整数类型的操作数的类型。
这意味着long int
和unsigned int
都将转换为 unsigned long int
。
- 为什么 std::(i)ostream 将有符号/无符号字符视为文本而不是整数
- 警告 C4018:">=":VSC++ 2010 中的有符号/无符号不匹配
- 有符号/无符号不匹配,并且函数在转换为函数时不带2个参数
- 符号"重新声明(有符号/无符号,精度)与
- 有符号/无符号特征编程
- 有符号/无符号 int 不匹配
- 断言(true)警告有符号/无符号不匹配
- 有符号/无符号比较警告是什么意思
- 数组索引的类型:有符号/无符号整数先锋
- 没有兼容的方法来转换相同大小的有符号/无符号
- 溢出的有符号/无符号赋值及其结果
- C++隐式转换(有符号 + 无符号)
- 增强size_type的有符号/无符号比较和multi_array的索引
- 警告 C4018:'>':有符号/无符号不匹配
- c++自动重写有符号/无符号
- C++警告 C4018:"<":有符号/无符号不匹配
- 错误:comp. bet.有符号/无符号整数表达式
- gcc和有符号/无符号比较的奇怪警告行为
- Visual Studio 2013有符号/无符号整数数学行为不同时,求值表达式作为函数参数,编译器切换
- 整数提升,有符号/无符号,和打印