C语言 算术转换 unsigned signed int
2013-07-29 16:52
309 查看
在C语言中,如果运算符的两个操作符不相同,那么它们之间对进行一定的算术转化,然后再进行运算操作。说明这个规则之前,先看一个例子
大多数初次接触这个问题的人可能觉得输出结果应该是true true,实际上在编译器中的结果应该是true faluse
第一个true没有任何问题,而第二个却让人疑惑,-1<5是公认的,那为何unsigned 5的却变成false了呢?
事实上-1仍然是-1,5仍然是5,只是编译器默认的算术转化规则导致的。
根据现象推本质,我们猜测是因为-1被转化成了unsigned int ,也就是一个非常大的正数,所以它比5要大。实际就是这样,当int和unsigned比较的时候,int会被转化为unsigned型
再看下面这个:
有了上面的例子做参考,我们可以知道"-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
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
相关文章推荐
- C语言中,unsigned与signed类型转换
- C语言 unsigned 和 signed 类型相互转换深入理解
- C语言 unsigned 和 signed 类型相互转换深入理解
- C语言 unsigned 和 signed 类型相互转换深入理解
- C语言 unsigned 和 signed 类型相互转换深入理解
- C语言 unsigned 和 signed 类型相互转换深入理解
- C语言 unsigned 和 signed 类型相互转换深入理解
- C语言中signed与unsigned的转换
- 在C语言中,double、long、unsigned、int、char类型数据所占字节数
- C语言中char int转换问题
- 将 expression 转换为数据类型 int 时发生算术溢出
- 语言 unsigned 和 signed 类型相互转换深入理解
- 【C语言】【笔试题】编写一个函数itob(int n,char s[], int b),将整数n转换为以b进制的数。保存到s中。
- C语言中char int转换问题
- C语言中关于char类型存储的分析 以及signed与unsigned的区别
- 每日总结:sql 转换为int时发生算术溢出错误、DatePart()、DateAdd()、DateDiff()函数、Case when then
- unsigned 和 signed之间的转换关系
- int与unsigned等转换深入理解(二)
- 在C语言中,double、long、unsigned、int、char类型数据所占字节数
- C语言中char转换成int