关于C语言的隐式类型转换规则

基于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;
}

 

 关于C语言的隐式类型转换规则

 

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

上一篇:【C#】调用C++动态库传入unsigned char*类型


下一篇:用jquery修改默认的单选框radio或者复选框checkbox选择框样式