[英]unsigned int data types in c
请帮我区分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编译器。
在第一个程序中,
int
-3(FFFFFFFD)被转换为uint8_t
为253(FD)。 高阶字节被丢弃,因此它适合。 uint8_t
253(FD)通过符号扩展转换为int
到253(000000FD)。 在第二个节目中,
int
-3(FFFFFFFD)转换为unsigned int
4294967293(FFFFFFFD)。 不需要删除任何字节。 unsigned int
4294967293(FFFFFFFD)投射到int
为-3(FFFFFFFD)。 笔记:
从有符号到无符号的转换将遵循第6.3.1.3
节C99标准草案的有 符号和无符号整数中规定的规则,该规则说:
否则,如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。 49)
所以这意味着-3
将通过向该值添加UMAX +1
来转换为。 在uint8_t
的情况下,这是一个相对较小的值253
,它适合于一个有问题的int ,因此被转换为signed int而没有问题。
在第二种情况下,返回值为unsigned int ,转换后我们将得到一个相当大的值,实际上是std::numeric_limits<unsigned int>::max() + 1 - 3
。 哪个不适合签名的int这是溢出的,因此根据6.5
节第5段说明是不确定的行为:
如果在计算表达式期间发生异常情况(即,如果结果未在数学上定义或未在其类型的可表示值范围内),则行为未定义。
从积分类型转换为无符号整数类型的规则很简单:
根据需要添加/下接(目标类型的最大值+ 1)以适应。
从积分类型转换为signd积分类型的规则仍然更简单:
保留该值,如果超出范围,则转换未定义。
大多数现代实现(全部在Windows平台上)定义它以相应的unsigned
类型添加/减去相同的常量,直到它适合。
使用这些规则,第一个示例中从fb()
返回的转换是保值和ok:
-3 - > 256-3 = 253 - > 253
第二个示例中的返回值是超出范围的,因此是未定义的行为,但通常情况下:
-3 - > 2 CHAR_BIT * sizeof(int) -3 - > -3
奖金事实:
CHAR_BIT
是一个预处理器常量,给出一个字节的位数。 sizeof
是一个运算符,给出一个类型/变量中的字节数。 unsigned int应打印为%u
而不是%d
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.