C 类型转换

在 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 语言本身自带的隐式类型转换就够用了。

上一篇: C 运算符优先级

下一篇: C 注释

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号