在 C 语言中,类型转换指的是将 “一种数据类型” 转换为 “另一种数据类型”。C 语言常见的数据类型,我们已经在 “C 数据类型” 这一节详细介绍过了。对于 C 语言来说,它有以下 2 种类型转换。
- 隐式类型转换
- 显式类型转换
在 C 语言中,对于不同的数据类型进行运算,是必须先将两种数据类型转换为同一种数据类型,然后才能进行下一步计算的。
C 隐式类型转换
在 C 语言中,隐式类型转换也叫做 “隐式转换” 或 “自动转换”,它指的是 C 语言自动进行的类型转换。这种类型转换是 C 语言 “偷偷” 进行的,而不需要我们手动去执行,所以才叫隐式类型转换。比如一个整数和一个浮点数相加,C 语言就会先将整数转换为浮点数,然后再进行相加。
对于 C 语言的隐式类型转换,我们需要知道以下 4 点。
- 隐式类型转换是按照 “长度增加” 或 “精度增加” 的方向转换的。比如:
- short 和 int 运算:会先把 short 转换为 int 后,然后再进行运算。
- float 和 double 运算:会先将 float 转换为 double,然后再运算。
- 如果一个整型和浮点型运算,那么会将整型转换为浮点型,然后再运算。
- char 和 short 运算时,会先将它们转换为 int,然后再进行运算。
- 在赋值运算中,如果两边类型不同,等号右边的类型会转换为等号左边的类型。如果右边类型的长度比左边类型的精度要高,就会丢失一部分数据。
示例 1:“short + int” 的隐式转换
#include <stdio.h>
int main(void)
{
short a = 10;
int b = 20;
printf("%d", a + b);
return 0;
}运行结果如下。
30分析:
隐式类型转换是按照 “长度增加” 的方向转换的,这里将 short 和 int 相加,C 语言就会自动将较短的 short 转换为较长的 int。虽然从结果我们看不出来是什么类型,但存储在内存中的确实是 int 类型。对于这一点,我们有没有什么特殊的办法证明呢?其实是有的,那就是使用 sizeof() 函数。
示例 2:使用 sizeof() 函数
#include <stdio.h>
int main(void)
{
short a = 10;
int b = 20;
printf("%d", sizeof(a + b));
return 0;
}运行结果如下。
4分析:
在 C 语言中,我们可以使用 sizeof() 函数来获取某一个变量所占用的字节数,它返回的是一个整数。对于这个例子来说,sizeof(a+b) 返回的结果是 4,也就说明了 a + b 占用的字节数是 4 个。而 int 类型是 4 个字节,所以 a + b 其实就是 int 类型。
此外,小伙伴们可以自行试一下 float + double,然后判断一下结果又是怎样的。
示例 3:“int + float” 的隐式转换
#include <stdio.h>
int main(void)
{
int a = 10;
float b = 20.0;
printf("%f", a + b);
return 0;
}运行结果如下。
30.000000分析:
在这个例子中,我们将一个 int 和一个 float 进行相加。根据之前介绍的规则,如果一个整型和一个浮点型运算,会先将整型转换为对应的浮点型,然后再运算。所以这里会先将 a 转换为 float 类型,然后再运算。另外,a + b 的结果其实是一个 float 类型。
示例 4:“char + short” 的隐式转换
#include <stdio.h>
int main(void)
{
short a = 10;
char b = 'A';
printf("%d", a + b);
return 0;
}运行结果如下。
75分析:
a 是一个 short 类型,b 是一个 char 类型。当一个 short 和 char 相加时,会同时将它们先转换为 int 类型,然后再进行相加。对于 char 类型来说,其实就是先拿到它的 ASCII 码,然后再转换成 int 类型。
同样地,我们可以使用 sizeof() 函数来判断 result 的字节数,会发现结果是 4(即 4 个字节)。
示例 5:赋值运算的隐式转换
#include <stdio.h>
int main(void)
{
float a = 3.6;
int b = a;
printf("%d", b);
return 0;
}运行结果如下。
3分析:
在这个例子中,a 是一个 float 类型,b 是 int 类型。我们把 a 赋值给 b 时,由于等号左边是一个精度较低的类型,所以就会直接截断小数部分,因此 b 的值就是 3。
需要注意的是,int b = a; 并不会对 a 进行四舍五入,而是直接了当进行截断处理,干脆利落。
示例 6:使用隐式类型转换
#include <stdio.h>
int main(void)
{
float pi = 3.1415;
int r = 10;
int area = pi * r * r; // 计算圆的面积
printf("%d", area);
return 0;
}运行结果如下。
314分析:
在这个例子中,pi 是一个 float 类型,r 是一个 int 类型,所以 pi * r * r 返回的是一个 float 类型,最终 pi * r * r 的结果是 314.150000。对于赋值运算来说,如果左右两边的类型不同,那么就会将右边的类型转换为左边的类型,所以 area 最终结果是 314。
C 显式类型转换
隐式类型转换,是 C 语言自动进行的。而显式类型转换,指的是需要我们手动用代码 “强制” 进行转换的,所以显式类型转换又叫做 “强制类型转换”。
语法:
(类型符)值
(类型符)(表达式)说明:
对于 C 语言的显式类型转换,小伙伴们需要注意以下 2 点。
- 如果是将某一个值或一个变量进行显式类型转换,值或变量加不加括号都可以,比如 (float)10 和 (float)(10) 这两个是等价的。
- 如果是将一个表达式进行显式类型转换,为了确保优先级正确,强烈建议表达式加上括号,比如 (float)(10+20)。
示例 7:使用显式类型转换
#include <stdio.h>
int main(void)
{
float a = 3.6;
float b = 10.6;
int result = (int)a + (int)b;
printf("%d", result);
return 0;
}运行结果如下。
13分析:
需要注意的是,“先求和再转换” 与 “先转换再求和”,结果可能不一样!因为浮点数的小数部分相加可能会进位,比如:
// 方式 1
int result = (int)a + (int)b; // result 的值为 13
// 方式 2
int result = (int)(a + b); // result 的值为 14这里小伙伴就有疑问了:“就算我们不对 a 和 b 进行显示转换,因为等号左边 result 的类型是 int,C 语言本身也会自动转换(隐式类型转换)啊。” 确实是这样的,对于上面这个例子来说,int result = (int)a + (int)b; 和 int result = a+b; 这两句代码没有什么区别,result 最终的值都是 13。
但在某些情况下,我们却需要使用显式类型转换来转换类型,请看下面例子。
示例 8:C 显式类型转换的应用
#include <stdio.h>
int main(void)
{
float a = 3.1415;
float b = 10.81;
printf("%d", (int)(a+b));
return 0;
}运行结果如下。
13分析:
上一个例子我们使用了一个 int 类型的变量来接收 a + b 的值,所以会触发隐式类型转换。但这里的 a + b 只是一个表达式,并没有赋值给另一个变量,所以不会触发隐式类型转换,此时就需要用到显式类型转换了。
在实际开发中,我们比较少去使用显式类型转换,因为大多数情况下 C 语言本身自带的隐式类型转换就够用了。
