C语言 算术转换 unsigned signed int

在C语言中,如果运算符的两个操作符不相同,那么它们之间对进行一定的算术转化,然后再进行运算操作。说明这个规则之前,先看一个例子

	int x = -1;
	int y = 5;
	unsigned int z = 5;
	if(x < y)
		printf("true ");
	else
		printf("false ");
	if(x < z)
		printf("true ");
	else
		printf("false ");


大多数初次接触这个问题的人可能觉得输出结果应该是true true,实际上在编译器中的结果应该是true faluse

第一个true没有任何问题,而第二个却让人疑惑,-1<5是公认的,那为何unsigned 5的却变成false了呢?

事实上-1仍然是-1,5仍然是5,只是编译器默认的算术转化规则导致的。

根据现象推本质,我们猜测是因为-1被转化成了unsigned int ,也就是一个非常大的正数,所以它比5要大。实际就是这样,当int和unsigned比较的时候,int会被转化为unsigned型

再看下面这个:

	if(x < (unsigned int)5)
		printf("-1 is less than int 5");
	if(x < (unsigned short)5)
		printf("-1 is less than short 5");


有了上面的例子做参考,我们可以知道"-1 is less than int 5"是不会打印的,后一句呢?

运行结果是"-1 is less than short 5",后面一句被打印出来了。这里有一个很有趣的情况,(unsigned int)5和(unsigned short)5 无疑是相等的,但和-1相比较它们又“不等了”

由上面两个例子可以一窥“算术转化”的规则,基于记忆,我们一般认为“数据类型一般朝着浮点精度更高,长度更长的方向转换,整型数如果转换为signed不会丢失信息,就转换为signed,否则转换为unsigned”

ANSI C(区别于K&R C)中,转换规则是这样的

如果一个数是long double,那么另一个数也被转换为long double,其次是double,再次是float;(语句意思同前一句,这里简化说明)

否则进行整型升级:同上面一样,首先如果一个数是unsigned long int,那么另一个数也被转换为unsigned long int

其次,对于long int unsigned int, 将后者转化为long int(int 是16位),或将两者都转化为unsigned long int(int 是32位),即一种类型能不能完全表示另一种类型

再次,有long int 则转化为该类型

再再次,有unsigned int 则转化为该类型

如果都不属于,则都做int 处理,即将short char都提升为int

 

依照这个规则,上述运行结果就可以解释了,主要问题是unsigned int 与int型的比较,结果可能超出预期,一般情况下,编译器是会给出警告信息的:

warning C4018: “<”: 有符号/无符号不匹配

 

----后话

也许有人会说,深究这个根本没有必要,程序中用强制类型转换就没有问题的。的确是这样,养成好的编程习惯,许多问题都能解决

要注意的是,常用的sizeof返回的就是unsigned int 型,如果将它的返回值与0比较没有问题,但是如果想当然地认为把0换成-1也一样的话,就很危险了。这也许不能算作是程序编写的bug,应该是C默认转换规则的bug

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值