最近在使用C语言做开发时遇见一些之前没注意过的问题,例如在做运算时,假设从内存(或者其他方式)中获取一个四字节的int数据,假设他是xxx乘10的7次方,而我需要的是10的6次方,即需要对获取的数据进“/10”操作。当时最大的疑问是我取得的数据是一个十六进制,而“/10”操作貌似是十进制的。这其实涉及到了运算时的自动类型转换,我猜想很多人这样使用过。
int main()
{
int int_num = 50;
float float_num = 0.0;
float_num = int_num / 5.0;
}
可以看见在代码中,由于“/5.0”,使得结果被自动转换为了float类型,那么也证明了在进行数据运算时,是可以自动进行类型转换的。
在这里先说下C语言运算中数据类型的自动转换,最后在文末说下开题所叙述的问题。
1、隐式转换
C在以下四种情况下会进行隐式转换:
1、算术运算式中,低类型能够转换为高类型。
2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。
2、算数运算的隐式转换
算数运算中,首先有如下类型转换规则:
1、字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) 。
2、short型转换为int型(同属于整型) 。
3、float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型) 。
其次,有下面的规则。
当不同类型的数据进行操作时,应当首先将其转换成相同的数据类型,然后进行操作,转换规则是由低级向高级转换。
低级--------------------------------------------------------------------------------->高级<------------低级
(char or short) -------> (int) -------> (unsigned) -------> (long) -------> (double) <------- (float)
有符号数与无符号数之间运算:当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此,从这个意义上讲,无符号数的运算优先级要高于有符号数,这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。
示例:
执行:x = 100 + 'a' + 1.5 * u + f / 'b' - s * 3.1415926
其中,u为unsigned型,f为float型,s为short型,x为float型。式中右面表达式按如下步骤处理:
1、首先将'a'、'b'和s换成int,将1.5和f转换为double型。
2、计算100+'a',因'a'已转换为int型,于是此运算结果为197。
3、计算1.5*u,由于1.5已转换为double,u是unsigned型,于是首先u转换为double,然后进行运算,运算结果为double。
4、计算197+1.5 * u,先将197转换为double(如197.00…00),其结果为double。
5、计算f/ 'b',f已转换为double,'b'已转换为int,于是先将'b'再转换为double,其结果为double。
6、计算(197+1.5 * u)+f / 'b',者均为double,于是结果也为double。
7、计算s * 3.1415926,先将s由int转换为double,然后进行运算,其结果为double。
8、最后与前面得的结果相减,结果为double。
9、最后将表达式的结果转换为float并赋给x。
看到这里应该会不会有个疑问,C语言都可以运算不同类型的数据了,那能不能运算不同进制的数据呢,答案当然是 可以!首先考虑个问题,计算机储存数据时是不是存储的二进制?十六进制也好,八进制也好,十进制也行,最后储存时是不是都是二进制,说到这里理解了吗。将两个数据(一个是十六进制,一个是十进制),进行运算,在定义变量时进行初始化赋值,或者后期给数据都可以,首先是将目标数据存储进去计算机,此时的数据就是以二进制的形式存储,再计算时也是使用二进制进行计算,计算晚的结果也是二进制,至于你装在什么类型的容器内就是你的事了。