基于C89标准下的隐式类型转换规则:
1.算术运算中或者逻辑判断表达式中操作式,不匹配的时候
2.赋值时,如果左右操作数类型不匹配
3.函数传递进去的实参和匹配的形参对应不上
4.函数返回的表达式的类型和函数返回类型不匹配
整值提升:将出现的字符类型(char)和短整型(short)统一提升为int类型(特殊情况下,也会提升为unsigned int)
1.如果左右操作数中存在浮点值
1.1如果一个操作数是long double,另一个操作数自动转换为long double
1.2如果一个操作数是double,另一个操作数自动转换为double
1.3如果一个操作数是float,另一个操作数自动转换为float
浮点值的优先级 long double > double > float
这一块操作数,浮点值和整形值混用
2.如果左右操作数中不存在浮点值
2.1首先整治提升(不要存在字符类型和短整型)
2.2 int < unsigned int < long < unsigned long
2.3特殊:如果两个操作数大小相等,并且一个是unsigned int,另一个是long int,则两个全部转换为unsigned long int
赋值语句:
左值大小 >= 右值大小 则自动转换
需要注意的点:
1.如果左边操作数类型 存储不下 右边操作数的值,则很危险
2.浮点值默认double,如果定义float a = 3.14; 会触发double转换为float,数据阶段
3.将浮点值赋值给整形值,会发生数据丢失(丢失小数点之后的数据)
案例测试:
#include <stdio.h>
#include <typeinfo>
int main()
{
char c;
short s;
unsigned short us;//unsigned short int us;
int i;
unsigned int ui;
long l;
unsigned long ul;
float f;
double d;
long double ld;
printf("%d\n", sizeof(c+s));//int
printf("%s\n", typeid(c+s).name());//int
printf("%s\n", typeid(c+us).name());//int
printf("%s\n", typeid(s+us).name());//int
printf("%s\n", typeid(us+i).name());//int
printf("%s\n", typeid(i+ui).name());//ui
printf("%s\n", typeid(i+l).name());//l
printf("%s\n", typeid(ui+l).name());//unsigned long int
printf("%s\n", typeid(l+ul).name());//ul
printf("%s\n", typeid(f+s).name());//f
printf("%s\n", typeid(f+c).name());//f
printf("%s\n", typeid(f+i).name());//f
printf("%s\n", typeid(d+ui).name());//d
printf("%s\n", typeid(d+l).name());//d
printf("%s\n", typeid(ld+s).name());//ld
printf("%s\n", typeid(ld+i).name());//ld
return 0;
}
C99,相较于C89,多了一些数据类型(bool long long int, 复数类型)大体规则不变
C99将所有整型类型分等级:从高到低
1: long long int unsigned long long int
2: long int unsigned long int
3: int unsigned int
4: short int unsigned short int
5: char unsigned char signed char
6: bool
使用的时候,具体分两种情况:
1.操作数中带浮点值,和C89一致
2.操作数中如果不带浮点值:(4个条件,从上到下触发,触发其中一个则退出)
2.1: 如果两个操作数都是有符号类型或者都是无符号类型,小的向大的转化
2.2: 如果无符号操作数类型 >= 有符号操作数类型,则有符号向无符号操作数转换
2.3: 如果有符号操作数类型 > 无符号操作数类型,如果无符号操作数能表示的范围可以用有符号去表示,则无符号想有符号操作数转化
2.4: 两个同时向有符号类型的无符号类型转化
特殊:如果两个操作数大小相等,并且一个是unsigned int,另一个是long int,则两个全部转换为unsigned long int
3.所有的类型都可以转化bool类型,如果值为0转化为false 要不然则为true
强制类型转化:
(类型)表达式:类型->强行将表达式结果转化的数据类型
float = (float)3.14;
int a = (int)3.14;
这里的括号,一般看做单目运算符,优先级最高
关于隐式转换的一些题目
计算程序运行结果
1.
#include <stdio.h>
#define FUNC(x,y)(x>y)?'a':'b'
int main()
{
unsigned int a = 10;
char b = 1;
unsigned char c = -1;
printf("%c,%c\n", FUNC(a, b), FUNC(a, c));
return 0;
}
2.
int main()
{
int a = 10;
unsigned char b = -10;
unsigned int c = 10;
printf("%d\n", a + b);
return 0;
}
答案:
1. a,b 2. 256
第一个题unsigned char 类型取值范围是0-255,由于-1存储的补码为“11111111”,因此被转化成了255
第二题 不同类型进行比较,根据隐式类型转化规则unsigned char 被转化为unsigned int 因此-10也就变成了246