C语言类型转换

相信你在大学的时候

遇到过类型转换题

不知道有多少人对它会感到头疼

可能有些人觉得记不住

有些人理解不了

因此我来介绍一下我的记忆方法以及对此应有的理解

I.两种类型转换

类型转换分两种:

  1. ​隐式类型转换(自动转换)​​:编译器在编译时自动进行转换。
  2. ​显式类型转换(强制转换)​​:在代码编写时明确指定进行转换,格式为:(目标类型) 表达式。比方说(int)char = ‘A’就是在强制把char的类型转换成int。

而在做类型转换题,主要考的是​​隐式转换​

II.隐式类型转换的四大规则

整体而言

这些规则讲究个:​

向数据范围更大的类型转换,以保证精度不丢失​​。

这并不多难

因为在你学数据类型时

你就应该能记住char short int......这些以占用空间来计算的从小到大排列的顺序

当你能记住它们时

记这个也就很简单了

规则一:整型提升

在表达式计算中

所有比 int 类型“小”的整型(如 charshort 等)会首先被自动转换为 int 或 unsigned int

然后再参与计算

​ 这是因为CPU处理 int 类型效率最高

char a = 10, b = 20;
int c = a + b; // a和b先被提升为int,然后相加,结果也是int
规则二:赋值转换

当你进行赋值操作时,如a = b(a,b都是变量时),等号右边表达式的结果类型会转换为左边变量的类型

不要问为什么,因为这是C语言人为规定的语法

但是注意:​ 这可能发生“截断”或“精度丢失”:

  • ​浮点数 -> 整数​​:直接丢弃小数部分。
  • 长整型 -> 短整型​​:截掉高位字节,只保留低位字节。

例如这行代码:

int i;
float f = 3.14;
i = f; // i的值是3,小数部分被丢弃

long l = 0x12345678;
short s = l; // s的值是0x5678 (取决于系统字节顺序)
规则三:运算转换

当一个操作符(如 +-*/)的两个操作数类型不同时

编译器会将它们转换为共同的类型

而它遵循的顺序就是我前面说的当你记住char short int......时你比较好记的了

转换方向遵循以下层次(从下到上):

long double (最高)​
​↑​
double
​↑​
float
​↑​
unsigned long long
​↑​
long long
​↑​
unsigned long
​↑​
long
​↑​
unsigned int
​↑​
int (最低)​

有没有发现什么规律呢?

我来帮你总结我发现的总方向

你看看是不是这样:

由整数到小数,由原本到unsigned,由原本到更long,由小(粗略)到大(精准)

当你也发现这个规律的时候,你就会发现它们很好记了

int i = 10;
float f = 2.5;
double d = i + f; 
// 步骤1: i (int) 和 f (float) 类型不同
// 步骤2: 根据规则,int 向 float 转换?不对!看层次图,float在上,int在下。
//        正确顺序是:i 先被转换为 float,然后与 f 进行加法,得到 float 类型的结果
// 步骤3: 赋值给 d,float 结果再转换为 double

规则四:函数参数转换

在调用函数时

如果形参和实参类型不匹配

实参会转换为形参的类型

(在ANSI C之后,通常需要类型匹配,但老标准或某些情况仍会发生转换)

III.记忆程度

如果你做过类型转换的题目时

你可能会发现

很多类型都有它的范围

超出范围的值会溢出

那我们需不需要记住它们的确切范围呢?

答案是:​​不需要死记硬背所有细节,但必须掌握核心概念和关键范围。

你不需要像背课文一样记住 unsigned long long 的最大值

 18,446,744,073,709,551,615

但你​​必须有这些大致的概念​​:

char​ / ​unsigned char​非常小​​。char 大约 ±128,unsigned char 大约 0~255。
short​ / ​unsigned short​比较小​​。大约 ±3万2千, 无符号大约 6万5千。
int​足够大​​。大约 ±21亿。
unsigned int​很大​​。大约 0~42亿。
float​有小数,但精度有限​​。
double​精度更高​​。

其中你要记的数字就是这么些

这样足以应付绝大多数题目和实际工程

例如:

unsigned char a = 200;
unsigned char b = 100;
unsigned char c = a + b; // 请问c的值是多少?

计算 a + ba 和 b 都是小类型,会发生​​整型提升​

被提升为 int(通常是更大的类型)

200 + 100 = 300,这个结果是一个 int 类型的 300

现在要将 int 类型的 300 赋值给 unsigned char 类型的 c

由于我知道 unsigned char 的范围很小(最大255)

而300 > 255,所以一定会发生​​溢出/截断​

300 的二进制形式中,低8位的值就是最终存入 c 的值

300 - 256 = 44。所以 c = 44

在整个推理过程中

我只需要知道 unsigned char 的最大值是255左右

而不需要知道它精确是255

我知道“300 > 最大值”这个事实就足够我判断出会发生溢出了

而实际工程中,我们就干脆可以用代码来查询了

比方说:

#include <stdio.h>
#include <limits.h> // 整数极限
#include <float.h>  // 浮点数极限

int main() {
    printf("The maximum value of char is: %d\n", CHAR_MAX);
    printf("The maximum value of int is: %d\n", INT_MAX);
    printf("The maximum value of unsigned int is: %u\n", UINT_MAX);
    
    printf("The maximum value of float is: %e\n", FLT_MAX);
    return 0;
}

这就更不必非常严苛去记忆它们的范围了

IV.类型转换的意义

char a = 10, b = 20;
int c = a + b; // a和b先被提升为int,然后相加,结果也是int

不知道你在看到这段代码的时候

你有没有疑惑过

为什么我不直接用int来定义a,b呢?

为什么我偏要用char来定义

然后让它们自己转换呢?

这是因为char 通常占用 ​​1字节​

int 在大多数现代系统上占用 ​​4字节​

这也就是说

当你用int来定义a,b时

你要用更多的空间来储存a,b

可能用char来定义会多上转换的一步

使得代码计算效率稍微逊色一点

但它的空间占有确实只有int的四分之一

当数据量巨大时,节省的空间非常可观!

也就是说

这是​​空间效率计算效率​​的取舍

而这也就是类型转换的意义所在

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值