C语言 int和unsigned int 隐式转换

最近看到一段代码,如下:

int main(void)
{
	unsigned int a = 6;
	int b = -20;
	int c = (a+b>0)? 1 : 0;
	printf("%d\n",a+b);
	printf("%d\n",c);
	return 0;
}

看到这里就有点好奇了,a+b打印出来明明是-14,表达式为假,C怎么还是1呢?

这里就涉及到C语言的一个隐式转换和数据在机器里面存放的形式。

 注:如果带符号类型的值域包含了无符号类型所表示的值,就把无符号类型转化为有符号类型。否则两个操作数都转化为对应的无符号类型。

        很显然,带符号的值域int 没有包含住unsigned  int的值域。所以a+b都将转化为unsigned int类型。

        这里有个需要了解的小知识点,计算器是怎么分辨无符号还是有符号数据的?

https://blog.csdn.net/qq_40627648/article/details/84348233

        上面这篇文章讲的很详细。也就是在硬件层面是没有有符号和无符号之分的。

        数据的运算都是采用补码来计算。(死去的数电开始攻击我。。。)

unsigned int a = 6; 无符号数据(也就是正数)的原码、反码、补码都相同

00····0000 0110  (32位)

int b = -20 

原码:10····0001 0100(32位,后面都是)

反码:符号位不变(原码的首位位符号位),其他位取反

           10····1110 1011

补码:反码+1

            11····1110 1100(省略号全是1)

a+b 为补码相加:00····0000 0110 + 11····1110 1100 = 11····1111 0010(补码,省略号全为1)

也就是a+b的结构存放的是形式为:上面的补码,我们转为原码看看是不是-14;

11····1111 0010 ------> (取反)10···· 0000 1101 ---------> (+1)10···· 0000 1110 -------> -14

到此为此,我们再回头看看上面代码,a+b为unsigned int类型相加,结果也为unsigned  int类型。

上面说的,机器并不知道11····1111 0010这个是有符号数还是无符号数。

而a+b返回的肯定是unsigned int类型。所以默认读出来是一个无符号数,11···1111 0010 对应的无符号数是 4294967282

所以表达式为真,结果为1.

printf("%d")打印出来默认为有符号的。如果采用printf("%u")形式打印,则结果为4294967282

以上做一个记录。

还有个比较容易犯错的地方。sizeof的返回值为unsigned类型。切记直接和int类型的负数相加!!!!

### 回答1: 可以使用强制类型转换int类型转化unsigned int类型,例如:unsigned int a = (unsigned int)int_num;。需要注意的是,如果int_num的值为负数,则转化后的unsigned int类型的值可能会变化。 ### 回答2: int是有符号整型,可以表示负数和正数,而unsigned int是无符号整型,只能表示非负整数。 将int转化unsigned int的过程称为无符号整型的显式转换。在进行转换时,如果int的值为负数,则转换结果会溢出。 具体的转换规则如下: 1. 如果int的值为非负数,则无需进行转换,结果与原值相同。 2. 如果int的值为负数,转换结果的值等于int的绝对值加上无符号整型的最大值再加1。 例如,将-10转化unsigned int,最大值为4294967295(32位机器),则转换结果为4294967295 + 10 + 1 = 4294967306。 需要注意的是,进行无符号整型的显式转换可能会导致数据的精度丢失或溢出。转换结果可能与原值不同,因此在进行转换时要谨慎处理。 另外,还需要考虑无符号整型的变量在进行计算时可能出现的溢出问题。因为无符号整型的范围是[0, 2^n-1],其中n为整型的位数,超出范围会产生溢出。 总之,将int转化unsigned int是一种将有符号整型转换为无符号整型的操作,需注意数据精度丢失和溢出问题。 ### 回答3: 将int转化unsigned int主要是为了使有符号的整数类型转换为无符号的整数类型。在C++中,intunsigned int都是整数类型,但有符号整数类型可以表示正数、负数和零,而无符号整数类型只能表示非负数和零。 int类型占用的内存空间取决于编译器和操作系统的不同,一般情况下为4个字节。而unsigned int类型也占用4个字节,但它不使用一个字节表示正负号,而是将全部的比特位用于表示数值。 当我们将int转化unsigned int时,如果int的值为正数,其二进制表示无需改变,直接转化unsigned int类型即可。但如果int的值为负数,则需要进行转换。 在转换的过程中,int的二进制表示会被解释为对应的unsigned int值。具体规则如下:当int为负数时,其二进制表示会被解释为对应的补码形式,再将补码形式转换unsigned int的值。补码形式转换为无符号整数类型的值需要首先检查补码中最高位的符号位,如果为1则表示为负数,需要进行转换转换时需要先反码,再加1,最后得到unsigned int的值。 值得注意的是,将int转化unsigned int可能会导致数据溢出。因为unsigned int无法表示负数,所以转换后的结果可能会变成一个很大的正数。因此,在进行类型转换时需要注意数据范围,确保转换后的值在unsigned int的表示范围内。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值