C语言【类型转换】总结

前言

        在写了这么久的习题博客,我发现其中非常爱考查的一个知识就是类型的转换,比如不同类型之间的加减乘除、比较大小和赋值运算等,这里面涉及最为多的就是隐式类型转换,所以在此专门写一个关于类型转换的知识点总结,也希望大家多多支持,一起努力!

一、类型转换

        关于类型转换,只需要记住:两种类型有关联,才可以进行类型转换。并且我们没必要区分隐式类型转换和强制类型转换,其转换原则都是一样的,不同点在于隐式类型转换是自动完成的,而强制类型转换是需要我们介入后才可以完成。


这里需要注意的是,类型转换中会产生临时变量,临时变量都是右值,无法访问其地址空间


二. 关联的类型

关联类型例子类型转换的类型
整型之间

char、int、short、long、long long

unsigned系列

隐式类型转换
整型、浮点型整型、double、float隐式类型转换
bool、整型

true为1,false为0

0为false、非0为true

隐式类型转换
bool、指针

true为0x1、false为0x0 / NULL

NULL为false、非NULL为true

隐式类型转换
指针、整型强制类型转换
指针、指针强制类型转换
数组、指针数组名转换为首元素指针隐式类型转换

1. 整型之间

(1)赋值运算符:像左侧表达式类型转换

① 【低字节 = 高字节】高字节发生整型截断

② 【高字节 = 低字节】低字节发生整型提升
③ 【无符号 = 有符号】有符号转换为无符号,转换后注意最高位为数值位

④ 【有符号 = 无符号】无符号转换为有符号,转换后注意最高位为符号位

(2)算数运算符(+、 -、 *、 /、 >、 <、 ==、 !=)

有符号转换为无符号、低字节转换为高字节

(3)函数传参、函数返回值

传参时:按照行参类型转换

返回值:按照函数返回值类型转换

转换规则与赋值一致

2. 整型与浮点型

(1)赋值运算符:像左侧表达式类型转换

① 【整型 = 浮点型】浮点型舍去小数部分

② 【浮点型 = 整型】整型加小数部分

(2)算数运算符(+、 -、 *、 /、 >、 <、 ==、 !=)

整型转换为浮点型

(3)函数传参、函数返回值

传参时:按照行参类型转换

返回值:按照函数返回值类型转换

转换规则与赋值一致

3. bool与整型

(1)赋值运算符:像左侧表达式类型转换

① 【bool = 整型】非0为true、0为false

② 【整型= bool】true为1、false为0

(2)函数传参、函数返回值

传参时:按照行参类型转换

返回值:按照函数返回值类型转换

转换规则与赋值一致

(3)条件判断

整型转换为bool

4. bool与指针

(1)赋值运算符:像左侧表达式类型转换

① 【bool = 指针】非NULL为true、NULL为false

② 【指针= bool】true为0x1、false为0x0

(2)函数传参、函数返回值

传参时:按照行参类型转换

返回值:按照函数返回值类型转换

转换规则与赋值一致

(3)条件判断

指针 转换为 bool

5. 指针与整型

        因为指针是表示的地址,地址为十六进制数,而整型为十进制数,所以两者之间的转换,无非就是十进制数与十六进制数的变换,但是也需要注意字节大小,因为在32位机器上指针为4字节、在64位机器上指针为8字节。而int 为 4字节,可能会发生高字节向低字节转换,这种转换是会丢失一部分地址大小。

#include <stdio.h>
int main()
{
    //在VScode测出的指针大小为8字节
    printf("指针大小: %d\n", sizeof(void*));
    int a = 1;
    int* p = &a;
    int b = (int)p;
    printf("p = %p\n", p);
    printf("b = %x\n", b);
    return 0;
}

 通过结果来看,确实丢失了一部分地址,这需要注意!

解决办法: 注意隐式类型转换和printf的格式化输出

#include <stdio.h>
int main()
{
    //在VScode测出的指针大小为8字节
    printf("指针大小: %d\n", sizeof(void*));
    int a = 1;
    int* p = &a;
    long b = (long)p;
    printf("p = %p\n", p);
    printf("b = %lx\n", b);
    return 0;
}

6. 指针与指针

        任意类型的指针都可以自由的强制类型转换,只不过转换后的指针进行解引用以及加法操作时,可以申请移动或访问的字节大小不同

这里推荐两篇指针的博客,看完之后就理解上面说的内容了

详谈【指针解引用】与【指针加整数】_指针解引用之后-CSDN博客

三、 整型提升:

在面对低字节到高字节的转换,发生的就是整型提升(提升针对的是原本类型)

【规则】

1. 无符号数的提升,高位补0

2. 有符号数的提升,高位补符号位

四、整型截断

高字节转换为低字节,发生截断

【规则】

1. 截断从低位开始一个一个数,数到对应的字节处截断

2. 截断之后,如果是个无符号数,那最高位的数字就是数值位

3. 截断之后,如果是个有符号数,那最高位的数字就是符号位

### C语言中的类型转换方法 #### 隐式类型转换 隐式类型转换是指编译器会根据上下文环境自动完成的数据类型的转换,无需程序员显式指定。这种转换通常遵循由低级到高级的规则[^1]。 例如,在表达式的计算过程中,不同数据类型的变量参与运算时会发生隐式类型提升: ```c #include <stdio.h> int main() { char c = 'A'; // 字符型 int i = c; // 编译器自动将字符型转为整型 printf("i=%d\n", i); // 输出 ASCII 值 65 return 0; } ``` 在这个例子中,`char` 类型被隐式地转换为了 `int` 类型[^1]。 --- #### 显式类型转换(强制类型转换) 当隐式类型转换无法满足需求或者可能导致意外行为时,可以使用显式类型转换。显式类型转换需要程序员手动指定目标类型,并采用 `(type)` 的形式进行操作[^2]。 以下是几个常见的场景及其对应的代码示例: ##### 场景一:浮点数与整数之间的转换 在某些情况下,可能需要将浮点数截断为整数值或将整数扩展为浮点数。可以通过强制类型转换实现这一目的: ```c #include <stdio.h> int main() { double pi = 3.14159; int truncated_pi = (int)pi; // 将双精度浮点数转换为整数 printf("truncated_pi=%d\n", truncated_pi); float f = 10.5f; int n = (int)f; // 浮点数 -> 整数 printf("n=%d\n", n); return 0; } ``` 在此处,`(int)` 表达式用于将浮点数转换为整数,舍弃小数部分[^2]。 --- ##### 场景二:处理无符号与带符号类型间的差异 由于无符号类型和带符号类型的行为存在显著区别,因此在混合使用这些类型时可能会引发未预期的结果。通过显式类型转换可以帮助避免这些问题: ```c #include <stdio.h> void do_something() {} int main() { unsigned char a = 1; unsigned char b = 255; if (((int)(a - 5)) < 0) { // 强制将结果转换为 signed int do_something(); } if ((unsigned int)(b + b) > 300) { // 转换为更大的范围以防止溢出 do_something(); } return 0; } ``` 这里展示了如何利用显式类型转换来控制算术运算的结果范围并规避潜在问题[^4]。 --- #### 数据类型转换的方向性 需要注意的是,C 中的数据类型转换总是朝着更宽泛、更高阶方向发展——即从小范围类型向大范围类型转变[^3]。比如从 `char` 到 `short`, 再至 `int`, 接着是 `long`, 最终达到 `float/double`. 然而并非所有情况都严格按此顺序执行, 特定条件下也可能发生例外情形. --- ### 总结 无论是隐式还是显式类型转换,都是编程实践中不可或缺的一部分。前者简化了开发流程,后者则提供了更高的灵活性以及对程序运行细节更强掌控力。合理运用这两种机制能够有效减少错误率提高软件质量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

终将向阳而生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值