C语言 类型转换

C语言

基础概念:

类型转换一般是为了解决如下的一些问题:

  1. 算术运算中或者逻辑判断表达式中操作室,不匹配的时候。

  2. 赋值时,如果左右操作数类型不匹配。

  3. 函数传递进去的实参和匹配的形参对应不上。

  4. 函数返回的表达式的类型和函数返回类型不匹配。

出现上述问题我们一般会进行相应的类型转换
否则编程在调试的时候会出现警告甚至报错。

C语言中类型转换主要分为两种:

1. 隐式类型转换
2. 显示类型转换

隐式类型转换:编译器自动将左右操作数变成相同类型去计算。
显式类型转换:程序开发者主观上去将类型强制转换。

在类型转换的过程中首先明确 整值提升 的定义

整值提升:将出现的字符类型(char)和短整型(short)统一先提升为int型(特殊情况下,也会提升为unsigned int )

<一> 隐式类型转换:

因为在C89 和 C99中有一点点的差别 这里就分开讲解 。

C89:

整型类型:char,short, int, long ,long long (unsigned signed)
小数类型:float ,double

对应上述出现的那些问题进行说明:

一.算术运算中或者逻辑判断表达式

(明确浮点值的优先值:long double > double > float)

  • 如果左右操作数有浮点值。

1:如果一个操作数是long double 另一个操作数自动转换为 long double 。
2:如果一个操作数为double 另一个自动靠向double。
3:如果一个操作数是float 另一个操作数自动转换为float。

  • 如果左右操作数没有浮点值。

1:首先整值提升 不要存在字符类型和短整型。
2:从小到大转换 int -> unsigned int-> long -> unsigned long。
3:如果两个操作数 大小相等 并且一个是unsigned int 另一个是long int 则两个全部转换为 unsigned long int。

对于部分来说操作数浮点值和整型值混用

二.赋值语句

如果左值大小>=右值大小则自动转换

1:如果左边操作数类型存储不下右边操作数的值 则很危险 这个值为无效值
2:浮点值默认double 如果定义float a =3.14 转换为float 会触发double转换为float 数据阶段
3:将浮点值赋值给整型值,会发生数据丢失(丢失小数点后的数据)

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

使用的时候,具体分两种情况:

一.操作数中带浮点值

和C89一致(上面有讲到,此处不在进行赘述)

二.操作数中如果不带浮点值:

(下面4个条件,从上到下触发,触发其中一个则退出)

2.1: 如果两个操作数都是有符号类型或者都是无符号类型,小的向大的转化

2.2: 如果无符号操作数类型 >= 有符号操作数类型,则有符号向无符号操作数转换

2.3: 如果有符号操作数类型 > 无符号操作数类型,如果无符号操作数能表示的范围可以用有符号去表示,则无符号想有符号操作数转化

2.4: 两个同时向有符号类型的无符号类型转化

特殊如果两个操作数大小相等,并且一个是unsigned int,另一个是long int,则两个全部转换为unsigned long int

三.所有的类型都可以转化bool类型

如果值为0转化为false 要不然则为true。

<二> 显式类型转换:

显式类型转换也称作强制类型转换。

一般写法:(类型)表达式

类型->强行将表达式结果转化的数据类型。

在强转中的括号一般看作单目运算符,优先级最高。

验证:

在验证隐式类型转换需要用到头文件 :’‘typeinfo’'

验证算术运算中的隐式类型转换格式为:
printf("%s\n", typeid(类型+类型).name());

验证代码如下:

#include 
#include 
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));
	printf("%s\n", typeid(c+s).name());
	printf("%s\n", typeid(c+us).name());
	printf("%s\n", typeid(s+us).name());
	printf("%s\n", typeid(us+i).name());
	printf("%s\n", typeid(i+ui).name());
	printf("%s\n", typeid(i+l).name());
	printf("%s\n", typeid(ui+l).name());
	printf("%s\n", typeid(l+ul).name());

	printf("%s\n", typeid(f+s).name());
	printf("%s\n", typeid(f+c).name());
	printf("%s\n", typeid(f+i).name());
	printf("%s\n", typeid(d+ui).name());
	printf("%s\n", typeid(d+l).name());
	printf("%s\n", typeid(ld+s).name());
	printf("%s\n", typeid(ld+i).name());

	return 0;
}

验证结果:
C语言 类型转换_第1张图片
特别注意:printf("%s\n", typeid(ui + l).name()); 的这个类型为unsigned long int

强转需要注意的问题:这里的括号,一般看做单目运算符,优先级最高

float f = (float)(a/b);//error
float f = (float)a/b;//ok
float f = a/(float)b;//ok
float f = (float)a/(float)b;//ok

你可能感兴趣的:(c语言,c语言,开发语言,后端)