比较值

时间:2017-04-24 14:26:41

标签: c

我对以下2个代码段有疑问。

我在64位计算机上运行此代码(x86_64-linux-gnu)。当数据类型为Val时,我可以看到值unsigned integer溢出。

#include<stdio.h>
main()
{
    unsigned int Val = 0xFFFFFFFF-15, Val2 = 0xFFFFFFFF;
    if (Val+16 < Val2)
    {
        printf("Val is less than Val2\n");
    }
}

如果数据类型为unsigned char,则不会溢出。

#include<stdio.h>
main()
{
    unsigned char Val = 0xFF-15, Val2 = 0xFF;
    if (Val+16 < Val2)
    {
        printf("Val is less than Val2\n");
    }
}

我有两个问题:

  
      
  1. 当数据类型为unsigned char时,值Val是否会被提升为高数据类型?
  2.   
  3. 如果是,为什么不将它从32位升级到64位unsigned long
  4.   

2 个答案:

答案 0 :(得分:6)

C11标准说明如下(C11 6.3.11p2.2):

  

如果int可以表示原始类型的所有值(受宽度限制,对于位字段),则该值将转换为int;否则,它将转换为unsigned int。这些被称为整数促销。 所有其他类型的整数促销都不会更改。

因此:

  1. unsigned char将被宣传 - 但是int是否可以代表unsigned char的所有值,这是一个实施细节 - 因此可能会提升为unsigned int在那些平台上。你的不是这些平台之一,因此你的第二个比较是(int)Val + 16 < (int)Val2

  2. 作为引用段落的最后一句话,unsigned int永远不会被提升。由于算法是在第一个片段中的无符号整数上完成的,因此0xFFFFFFFF - 15 + 16的结果在具有32位无符号整数的计算机上为0U

答案 1 :(得分:2)

是的,在第二种情况下,数字会提升为int。如果您修改代码:

#include<stdio.h>
int main()
{
    unsigned char Val = 0xFF-15, Val2 = 0xFF;
    if ((unsigned char)(Val+16) < Val2)
    {
        printf("Val is less than Val2\n");
    }
}

您将获得您期望的行为。