c中的unsigned int数据类型

时间:2014-07-02 15:09:20

标签: c types implicit-conversion

请帮我区分C:

中的这些代码

代码1:

#include<stdio.h>
#include <stdint.h>

uint8_t fb(int a)
{
    return -3;
}

int main()
{
    int a = fb(-3);
    printf("%d",a);
    return 0;
}

代码2:

#include<stdio.h>

unsigned int fb(int a)
{
    return -3;
}

int main()
{
    int a = fb(-3);
    printf("%d",a);
    return 0;
}

问题是第一个代码按预期返回253但第二个代码返回-3,这是意外的,因为返回类型是无符号的。请帮助我如何做到这一点?

我使用过mingw gcc编译器。

4 个答案:

答案 0 :(得分:9)

在第一个程序中,

  1. 当函数返回时,int -3(FFFFFFFD)被强制转换为uint8_t为253(FD)。高阶字节被丢弃,因此它适合。
  2. 执行作业时,uint8_t 253(FD)通过符号扩展名转换为int至253(000000FD)。
  3. 在第二个程序中,

    1. 当函数返回时,int -3(FFFFFFFD)强制转换为unsigned int 4294967293(FFFFFFFD)。没有字节需要删除。
    2. 执行分配时,unsigned int 4294967293(FFFFFFFD)强制转换为int为-3(FFFFFFFD)。
    3. 注意:

      • 假设32位整数,但它与64位整数类似。
      • 这是对你发生的事情的解释;它不一定是C规范要求发生的事情。

答案 1 :(得分:2)

从已签名到无签名的转换将遵循6.3.1.3 draft C99 standard的有符号和无符号整数部分中规定的规则,其中包含:

  

否则,如果新类型是无符号的,则转换为   重复加或减一个以上的最大值   可以用新类型表示,直到值在范围内   新类型。 49)

因此,这意味着-3将通过向值添加UMAX +1来转换为uint8_t。在253的情况下,这是一个相对较小的值std::numeric_limits<unsigned int>::max() + 1 - 3,它适合 singed int ,因此可以毫无问题地转换为 signed int

在第二种情况下, unsigned int 的返回值,转换后我们将得到一个相当大的值,实际上是6.5。哪个不适合 signed int 这是溢出的,因此根据{em> 5 部分的{{1}}段说明未定义的行为:

  

如果在评估过程中出现异常情况   表达式(即,如果结果未在数学上定义或   不在其类型的可表示值的范围内),行为   未定义。

答案 2 :(得分:0)

从积分类型转换为无符号整数类型的规则很简单:
根据需要添加/下接(目标类型的最大值+ 1)。

从积分型转换为signd积分型的规则仍然比较简单:
保留该值,如果超出范围,则转换未定义 大多数现代实现(都在Windows平台上)定义它以相应的unsigned类型添加/减去相同的常量,直到它适合。

使用这些规则,第一个示例中从fb()返回的转换是保值并且确定:
-3 - &gt; 256-3 = 253 - &gt; 253

第二个例子中的返回是超出范围的,因此是未定义的行为,但通常是:
-3 - &gt; 2 CHAR_BIT * sizeof(int) -3 - &gt; -3

奖金事实:

  • 将可变参数函数传递为有符号/无符号类型,其中允许使用相应的其他类型,但原始值无法转换,只能假定为指定类型。
  • CHAR_BIT是一个预处理器常量,给出一个字节的位数。
  • sizeof是一个运算符,它给出了类型/变量中的字节数。

答案 3 :(得分:0)

unsigned int应打印为%u而不是%d