隐式类型转换规则:
C语言自动转换不同类型的行为称之为隐式类型转换 ,转换的基本原则是:低精度类型向高精度类型转换,具体是:
int -> unsigned int -> long -> unsigned long -> long long -> unsigned long long -> float -> double -> long double
注意,上面的顺序并不一定适用于你的机器,比如当int和long具有相同字长时,unsigned int的精度就会比long的精度高(事实上大多数针对32机的编译器都是如此)。另外需要注意的一点是并没有将char和short型写入上式,原因是他们可以被提升到int也可能被提升到unsigned int。
提升数据的精度通常是一个平滑无损害的过程,但是降低数据的精度可能导致真正的问题。原因很简单:一个较低精度的类型可能不够大,不能存放一个具有更高精度的完整的数据。一个1字节的char变量可以存放整数101但不能存放整数12345。当把浮点类型数据转换为整数类型时,他们被趋零截尾或舍入。
强制类型转换:
通常我们应该避免自动类型转换,当我们需要手动指定一个准确的数据类型时,我们可以用强制类型转换机制来达到我们的目的,使用方法很简单,在需要强制转换类型的变量或常量前面加上(type),例如(double)i; 即把变量 i 强制转换成double型。
---------------------------------------------------------------------------------------------
一个int型负数转换成一个unsigned int型数时为什么会变成一个很大的整数?这
这里涉及到整数的存储方式,整数的二进制有原码、反码、补码,
它在内存中的转换是:整形数据在内存中是以2进制数的补码存在的,
正数的原码、反码、补码都一样,而负数则不同,-3的原码是1000 0000 0000 0011(左边的第一个1表示符合位,1为负,0为正);反码是1111 1111 1111 1100(原码除符号位之外的所有为取反);补码是1111 1111 1111 1101(反码+1);输出时也按补码,所以最终二进制补码的值就是类型转换后的值,即b=65533(这是在TC2.0上的(16位))。
——————————————————————————————
开门见山,先来看一段简单的代码:
1 #include <stdio.h> 2 3 int array[] = {1, 2, 3, 4, 5, 6, 7}; 4 #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0])) 5 6 int main() 7 { 8 int i = -1; 9 int x; 10 11 if(i <= TOTAL_ELEMENTS - 2) { 12 x = array[i + 1]; 13 printf("x = %d.\n", x); 14 } 15 16 printf("now i = %d.\n", TOTAL_ELEMENTS); 17 18 return 0; 19 }
执行结果:
[email protected]:~/C_Language$ ./a.out
now i = 7.
是不是很奇怪?为什么没有打出line13的x = ?。
是这样的。这个小例子有三点值得注意:
1.sizeof()是运算符,返回类型是无符号的,即非负数。
2.if语句在singned int和unsigned int之间进行判断语句,根据C语言的整型提升规则,如果原始类型的所有值都可用int类型表示,则其值将被转换为int类型;否则将被转换为unsigned int类型。因此此时的i将会被升级成无符号类型。
3.i = -1被升级为无符号型,值究竟是多少?这要用到整型转换规则:K&R上这样解释,将任何整数转换为某种指定的无符号数类型数的方法是:以该无符号数类型能够表示的最大值加1为摸,找出与此整数同余的最小的非负值。听着很拗口,其实说白了,只要知道原整数的二进制表达方法,再用要即将转换的类型去解析,就得到升级后的值了。 比如-1,负数在计算机里用补码表示,0xffffffff,那升级成无符号型之后,值就是0xffffffff,显然比TOTAL_ELEMENTS(7)大。
————————————————————————————