最近看到一道经典例题:
看代码
#include <stdio.h>
int main(){
unsigned int a = 6;
int b = -20;
(a+b)>6?printf(">6\n"):printf("<6\n");
return 0;
}
结果是 >6
为什么呢?这里涉及到了隐式转换的问题》》》》》
C在以下四种情况下会进行隐式转换:
1、算术运算式中,低类型能够转换为高类型。2、赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
3、函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
4、函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。
1、算术运算的隐式转换
算数运算中,首先有如下类型转换规则:
1、字符必须先转换为整数(C语言规定字符类型数据和整型数据之间可以通用) 。
2、short型转换为int型(同属于整型) 。
3、float型数据在运算时一律转换为双精度(double)型,以提高运算精度(同属于实型) 。
其次,有下面的规则。
当不同类型的数据进行操作时,应当首先将其转换成相同的数据类型,然后进行操作,转换规则是由低级向高级转换。转换规则如图所示;
当表达式中存在有符号类型和无符号类型时所有的操作数都自动转换为无符号类型。因此,从这个意义上讲,无符号数的运算优先级要高于有符号数,这一点对于应当频繁用到无符号数据类型的嵌入式系统来说是丰常重要的。
#include <stdio.h>
int main()
{
unsigned int a = 6;
int b = -20;
(a>b)?printf(">\n"):printf("<\n");
return 0;
}
结果:<
因为在C语言中,有符号数与无符号数同时存在的操作,有符号数会隐式转换成无符号数,结果b会变成一个很大的无符号数。
减法和乘法的运算结果类似。
但如果是signed int 型数据与立即数操作时,结果仍是signed int 型
#include <stdio.h>
int main(){
int b = -130;
printf("%d\n",b+30 );
return 0;
}
结果:-100;
而对于浮点数来说,浮点数(float,double)实际上都是有符号数,unsigned 和signed前缀不能加在float和double之上,当然就不存在有符号数跟无符号数之间转化的问题了。
最后有个疑问:
#include <stdio.h>
int main()
{
unsigned int i = 3;
printf("%d\n",i* -1);
return 0;
}结果是-3;
在c++中:
#include <iostream>
using namespace std;
int main()
{
unsigned int i = 3;
cout << i* -1 << endl;
return 0;
}在表达式i*-1中,i是unsigned int型,-1是int型(常量整数的类型同enum),可以知道-1必须转换为unsigned int型,即0xffffffff,十进制的4294967295,然后再与i相乘,即4294967295*3,如果不考虑溢出的话,结果是12884901885,十六进制0x2FFFFFFFD,由于unsigned int只能表示32位,因此结果是0xfffffffd,即4294967293