- C编程教程
- C语言 - 首页
- C语言基础
- C语言 - 概述
- C语言 - 特性
- C语言 - 历史
- C语言 - 环境搭建
- C语言 - 程序结构
- C语言 - Hello World
- C语言 - 编译过程
- C语言 - 注释
- C语言 - 词法单元
- C语言 - 关键字
- C语言 - 标识符
- C语言 - 用户输入
- C语言 - 基本语法
- C语言 - 数据类型
- C语言 - 变量
- C语言 - 整数提升
- C语言 - 类型转换
- C语言 - 类型强制转换
- C语言 - 布尔值
- C语言中的常量和字面量
- C语言 - 常量
- C语言 - 字面量
- C语言 - 转义序列
- C语言 - 格式说明符
- C语言中的运算符
- C语言 - 运算符
- C语言 - 算术运算符
- C语言 - 关系运算符
- C语言 - 逻辑运算符
- C语言 - 位运算符
- C语言 - 赋值运算符
- C语言 - 一元运算符
- C语言 - 自增和自减运算符
- C语言 - 三元运算符
- C语言 - sizeof运算符
- C语言 - 运算符优先级
- C语言 - 其他运算符
- C语言中的决策
- C语言 - 决策
- C语言 - if语句
- C语言 - if...else语句
- C语言 - 嵌套if语句
- C语言 - switch语句
- C语言 - 嵌套switch语句
- C语言中的循环
- C语言 - 循环
- C语言 - while循环
- C语言 - for循环
- C语言 - do...while循环
- C语言 - 嵌套循环
- C语言 - 无限循环
- C语言 - break语句
- C语言 - continue语句
- C语言 - goto语句
- C语言中的函数
- C语言 - 函数
- C语言 - 主函数
- C语言 - 按值调用函数
- C语言 - 按引用调用函数
- C语言 - 嵌套函数
- C语言 - 可变参数函数
- C语言 - 用户自定义函数
- C语言 - 回调函数
- C语言 - return语句
- C语言 - 递归
- C语言中的作用域规则
- C语言 - 作用域规则
- C语言 - 静态变量
- C语言 - 全局变量
- C语言中的数组
- C语言 - 数组
- C语言 - 数组的特性
- C语言 - 多维数组
- C语言 - 将数组传递给函数
- C语言 - 从函数返回数组
- C语言 - 变长数组
- C语言中的指针
- C语言 - 指针
- C语言 - 指针和数组
- C语言 - 指针的应用
- C语言 - 指针运算
- C语言 - 指针数组
- C语言 - 指向指针的指针
- C语言 - 将指针传递给函数
- C语言 - 从函数返回指针
- C语言 - 函数指针
- C语言 - 指向数组的指针
- C语言 - 指向结构体的指针
- C语言 - 指针链
- C语言 - 指针与数组
- C语言 - 字符指针和函数
- C语言 - 空指针
- C语言 - void指针
- C语言 - 悬空指针
- C语言 - 解引用指针
- C语言 - 近、远和巨型指针
- C语言 - 指针数组的初始化
- C语言 - 指针与多维数组
- C语言中的字符串
- C语言 - 字符串
- C语言 - 字符串数组
- C语言 - 特殊字符
- C语言中的结构体和联合体
- C语言 - 结构体
- C语言 - 结构体和函数
- C语言 - 结构体数组
- C语言 - 自引用结构体
- C语言 - 查找表
- C语言 - 点(.)运算符
- C语言 - 枚举(enum)
- C语言 - 结构体填充和打包
- C语言 - 嵌套结构体
- C语言 - 匿名结构体和联合体
- C语言 - 联合体
- C语言 - 位域
- C语言 - typedef
- C语言中的文件处理
- C语言 - 输入输出
- C语言 - 文件I/O (文件处理)
- C语言预处理器
- C语言 - 预处理器
- C语言 - 编译指示
- C语言 - 预处理器运算符
- C语言 - 宏
- C语言 - 头文件
- C语言中的内存管理
- C语言 - 内存管理
- C语言 - 内存地址
- C语言 - 存储类别
- 其他主题
- C语言 - 错误处理
- C语言 - 可变参数
- C语言 - 命令执行
- C语言 - 数学函数
- C语言 - static关键字
- C语言 - 随机数生成
- C语言 - 命令行参数
- C编程资源
- C语言 - 问答
- C语言 - 快速指南
- C语言 - 速查表
- C语言 - 有用资源
- C语言 - 讨论
C语言中的类型转换
C编译器尝试进行数据类型转换,尤其是在表达式中出现不同数据类型时。在某些情况下,编译器会自行进行转换(隐式类型转换),以确保数据类型兼容。在其他情况下,C编译器会强制执行转换(显式类型转换),这由类型强制转换运算符执行。
C语言中的隐式类型转换
在C语言中,隐式类型转换在编译器将赋值给变量的值的类型转换为另一种数据类型时自动发生。这通常发生在将字节大小较小的类型赋值给“较大”的数据类型时。在这种隐式数据类型转换中,数据完整性得以保留。
在执行隐式或自动类型转换时,C编译器遵循类型提升规则。通常遵循的原则是:
字节和短整型值:它们被提升为int。
如果一个操作数是long:整个表达式被提升为long。
如果一个操作数是float:整个表达式被提升为float。
如果任何操作数是double:结果被提升为double。
整数提升
整数提升是将小于int或unsigned int的整数类型的值转换为int或unsigned int的过程。
示例
考虑一个将字符与整数相加的示例:
#include <stdio.h> int main(){ int i = 17; char c = 'c'; /* ascii value is 99 */ int sum; sum = i + c; printf("Value of sum: %d\n", sum); return 0; }
输出
运行此代码时,将产生以下输出:
Value of sum: 116
这里,sum的值是116,因为编译器正在进行整数提升并将“c”的值转换为ASCII码,然后执行实际的加法运算。
通常的算术转换
通常的算术转换是隐式执行的,将它们的值转换为公共类型。编译器首先执行整数提升;如果操作数的类型仍然不同,则它们将转换为以下层次结构中出现最高的类型:
示例
这是另一个隐式类型转换的示例:
#include <stdio.h> int main(){ char a = 'A'; float b = a + 5.5; printf("%f", b); return 0; }
输出
运行代码并检查其输出:
70.500000
当上述代码运行时,char变量“a”(其int等效值为70)被提升为float,因为加法表达式中的另一个操作数是float。
C语言中的显式类型转换
当需要将字节大小较大的数据类型转换为字节大小较小的数据类型时,需要明确告知编译器您的意图。这称为显式类型转换。
C提供了一个类型强制转换运算符。需要在要转换的操作数之前加上数据类型括号。
type2 var2 = (type1) var1;
请注意,如果type1的长度小于type2,则不需要这种显式强制转换。只有当type1的长度大于type2时,才应使用类型强制转换运算符。
当需要将更大的数据类型变量降级为较小的变量或在不相关的类型(如float到int)之间转换时,需要进行类型强制转换。
示例
考虑以下代码:
#include <stdio.h> int main(){ int x = 10, y = 4; float z = x/y; printf("%f", z); return 0; }
输出
运行此代码后,您将获得以下输出:
2.000000
虽然我们期望结果为10/4(即2.5),但它显示为2.000000。这是因为除法表达式中的两个操作数都是int类型。在C语言中,除法运算的结果始终是字节长度较大的数据类型。因此,我们必须将其中一个整数操作数强制转换为float,如下所示:
示例
看看这个例子:
#include <stdio.h> int main(){ int x = 10, y = 4; float z = (float)x/y; printf("%f", z); return 0; }
输出
运行代码并检查其输出:
2.500000
如果我们更改表达式,使得除法本身强制转换为float,则结果将不同。
C语言中的类型转换函数
标准C库包含许多执行类型转换的函数。这里解释其中一些函数:
atoi()函数
atoi()函数将字符串转换为整数值。该函数在stdlib.h头文件中声明。
示例
以下代码使用atoi()函数将字符串“123”转换为数字123:
#include <stdio.h> #include <stdlib.h> int main(){ char str[] = "123"; int num = atoi(str); printf("%d\n", num); return 0; }
输出
运行代码并检查其输出:
123
itoa()函数
可以使用itoa()函数将整数转换为以null结尾的字符字符串。该函数在stdlib.h头文件中声明。
示例
以下代码使用itoa()函数将整数123转换为字符串“123”:
#include <stdio.h> #include <stdlib.h> int main(){ int num = 123; char str[10]; itoa(num,str, 10); printf("%s\n", str); return 0; }
输出
运行代码并检查其输出:
123
使用类型强制转换的其他示例包括:
malloc()函数 - malloc()函数是动态内存分配函数。
Int *ptr = (int*)malloc(n * sizeof(int));
在函数参数和返回值中 - 可以将类型强制转换运算符应用于形式参数或用户定义函数的返回值。
示例
这是一个例子:
#include <stdio.h> #include <stdlib.h> float divide(int, int); int main(){ int x = 10, y = 4; float z = divide(x, y); printf("%f", z); return 0; } float divide(int a, int b){ return (float)a/b; }
输出
运行此代码时,将产生以下输出:
2.500000
在C语言中使用隐式或显式类型转换有助于提高类型安全性和代码可读性,但也可能导致精度损失,其复杂的语法也可能令人困惑。