gpt4 book ai didi

C++ 隐式转换(有符号 + 无符号)

转载 作者:IT老高 更新时间:2023-10-28 21:41:29 24 4
gpt4 key购买 nike

我了解,关于隐式转换,如果我们有一个无符号类型操作数和一个有符号类型操作数,并且无符号操作数的类型与有符号操作数的类型相同(或大于),则有符号操作数将被转换为无符号。

所以:

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 将被转换为signed long long,因为int 值可以适合signed long long??

如果是这样,在什么情况下较小的类型值不适合较大的类型值?

最佳答案

标准中的相关引用:

5 个表达式 [expr]

10 Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

[关于等号类型或等号类型省略的2条子句]

— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

— Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type.

— Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

让我们考虑以下 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
}

Live example 带输出。

第一个子句:相等等级的类型,所以 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制作 unsignedu 明确表示后缀相同的规则适用。在用 C++ 编写时比较 -4 < 2 时,结果可能不是您所期望的 -4 < 2u ...

关于C++ 隐式转换(有符号 + 无符号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17832815/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com