C ++中有符号和无符号之间的转换

时间:2013-04-14 03:45:12

标签: c++ casting

考虑以下C ++代码:

#include <cstdio>

using namespace std;

int main()
{
    int ia = -5;
    unsigned int uia = ia;
    char ca = -5;
    unsigned char uca = ca;

    printf("%d\n", (ia == uia));
    printf("%d\n", (ca == uca));

    return 0;
}

输出

1
0

我不明白从int转换为charsignedunsigned之间的区别是什么?

你能告诉我吗?

3 个答案:

答案 0 :(得分:6)

从有符号转换为无符号时,它们的行为都相同。 ==比较的行为有所不同。它的行为符合int / unsigned的预期,但是当你比较两个较小的类型时,它们都会首先被提升为int。所以会发生的是-5和-5的无符号8位表示都被提升为int然后进行比较。这些显然是不同的,未能通过比较。

答案 1 :(得分:1)

好的,这种不一致行为的实际原因是char和unsigned的基础推广。我想更具体地解释一下。

首先,当使用int和unsigned int变量进行比较时,它们的类型无关紧要,因为无论它们是什么类型,它们在内存中都具有相同的二进制表示,这就是== operator cares。

当==应用于char和unsigned char varialbes时,它们将首先扩展为相应的32位整数类型,并且它们如何被显示是不一致的关键。由于 ca 是一个char,它将使用符号位(通过MOVSX)进行扩展,而 uca 将仅使用填充0(通过MOVZX)进行扩展。因此,它们现在具有不一致的二进制表示。

汇编代码说明了这一点。

    int b1 = ia == uia;
000613E5  mov         eax,dword ptr [ia]  
000613E8  xor         ecx,ecx  
000613EA  cmp         eax,dword ptr [uia]  
000613ED  sete        cl  
000613F0  mov         dword ptr [b1],ecx  
    int b2 = ca == uca;
000613F3  movsx       eax,byte ptr [ca]  
000613F7  movzx       ecx,byte ptr [uca]  
000613FB  xor         edx,edx  
000613FD  cmp         eax,ecx  
000613FF  sete        dl  
00061402  mov         dword ptr [b2],edx 

答案 2 :(得分:-3)

签名类型可以是负面的,也可以是正面的。虽然无符号值较高但不能为负值。

所以unsigned int的最大值分别为4,294,967,296。它的最小值是0.

而有符号int的范围是-2,147,483,648到2,147,483,648。

我希望这可以帮助您理解有符号和无符号类型之间的区别。

当您想要避免值为负时,此功能可以派上用场。比如参考数组。或者如果您只需要正值大且没有负数。为了节省你需要长时间。