今天做了几题关于C语言数据类型转换的题目,感觉自己是懂非懂,于是决定在研究研究。
首先,C语言数据类型的自动转换遵循以下规则(这是经常用到的,还有其他规则这里没有写齐全,可自行百度):
若参与运算量的类型不同,则先转换成同一类型(更高的),然后进行运算。
转换按数据长度增加的方向进行,以保证精度不降低。如int型和long型运算时,先把int量转成long型后再进行运算。
a. 若两种类型的字节数不同,转换成字节数高的类型
b. 若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型- 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
一、我们直接上例题来分析:
①
#include<stdio.h>
int main()
{
unsigned int a=5;
int b=-10;
(a+b>6)?printf(">6"):printf("<=6");
return 0;
}
结果:
这里运用到了2.b的规则,将signed int b,在运算是提升为 unsigned。
b = -10;在计算机中的负数一补码形式存在,就是0xfffffff6,转换为unsigned为4294967286,所以a+b = 5 + 4294967286 = 4294967291;调试也是这个值(结果还有编译器有关)
②
有定义(tip:潜在的级数升级,此处按int输出)
signed char ch = 127;
printf(“%d”,ch+127);
输出结果是254;
如果以上改为:
signed char ch = 127;
ch = ch + 127;
printf("ch = %d\n",ch);
输出结果是-2;
为什麼是这这样呢?我们再看一个例题:
③
#include <stdio.h>
int main()
{
int i = 1,x = 1;
float j = 3.5, y = 3.5;
i = i + j;//这里应该是把3.5截取为3,或者1升级为1.0,相加后为4.5,赋给i,截取为int,最终为int类型
printf("i = %d\n",i);//%d显示: i = 4
printf("i = %f\n",i);//%f显示: i = 0.000000,结果错误,所以i不为double/float类型
printf("x + y = %d\n",x + y);//%d显示:x + y = 0结果错误,所以x+y不为int类型,类型提升为double类型
printf("x + y = %f\n",x + y);//%f显示:x + y = 4.500000
return 0;
}
根据②③来两个例子,在说明之前强调一点:printf函数中,指定的输出类型和输出表列的类型如果不一致,能通过编译,但是不能正确输出结果。
它们运用的规则为1和3,
1. 若参与运算量的类型不同,则先转换成同一类型(更高的),然后进行运算。
3. 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
ch = ch + 127; 和i = i + j;
首先存在不同类型的运算,ch + 127; i + j;根据1规则,会提升类型,ch + 127变为int类型,i+j变为double(j为float,i为int,它们最终都会提升为double类型),然后就是不类型的赋值,运用到3规则,ch = ch + 127;(int — >char),i = i + j;(double—>int)然后结合例题③代码得注释去理解。
总结:存在不同类型运算,转换为相同类型(更高的)去运算,这个表达式变成这个更高的类型。并没有真正去改变变量的类型。当混合运算表达式赋值给某个变量时,如果表达式类型和变量类型不一致,表达式类型需要转换为变量类型( 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。)