【C】隐式类型转换

张开发
2026/4/11 18:31:08 15 分钟阅读

分享文章

【C】隐式类型转换
隐式类型转换是C语言在编译阶段自动进行的类型转换无需程序员显式指定。它主要用于以下场景表达式中操作数类型不同如int float赋值时左右类型不匹配如int float函数调用时参数类型不匹配如传递char给int形参隐式转换的核心目标是保证运算的合理性和精度但它可能带来意料之外的结果需谨慎处理。补充浮点数和整型数之间无论是隐式转换还是强转都是数值语义的转换1.0转成int就是1而不是内存值。只有用联合体或指针才能取浮点数特殊的存储格式。整型提升时规则低于int的在计算时不管需不需要都先统一到int即使两边都是char有符号类型高位填充符号位负数补1正数补0也适用于右移规则无符号类型高位补0unsigned char uc 0xFF; //11111111 int i uc; //提升为int - 00000000 00000000 00000000 11111111左移规则低位补0单字节左移会触发整型提升左移不大于24无需考虑强转uint64_t大于24则一定要先强转再左移右移规则无符号数高位补0有符号数高位补符号位两个操作数类型不同时按下方从低到高转换低优先级直接变成高优先级char/short - int- unsigned int - long - unsigned long - long long - unsigned long long - float - doubleunsigned int 比 int范围大每个int包括负数都可以找到对应点且计算逻辑没问题信息不丢失。如果反过来unsigned int的大值转成int变成了负数虽然在int范围内合法但是和原始数学意义完全割裂导致信息丢失char a -1; unsigned long aa 1; unsigned long long b 1; unsigned long long c a * b; unsigned long long d a * aa * b; printf(chenmin %lld %lld\n, c, d); //结果是chenmin -1 4294967295 //c是由a变int再变unsigned long long //d是由a变int再变unsigned long再变unsigned long long中间符号位丢失操作数精度相同则计算结果类型不变且中间过程无需转换。但是有需要的话我们可以借助整型提升时规则来理解过程和结果比如INT32U的5-255实际计算过程都是INT32U无需浪费资源我们可以先假设提升了得到-250再转成一个很大的INT32U之后再进行强转或者赋值操作。INT64U 0x1D000000 * 0x1D000000; //结果是0两个32位的数先相乘溢出再赋值INT64U (INT64U)(0x1D000000 * 0x1D000000); //结果是0两个32位的数先相乘溢出再赋值常见陷阱1、符号位扩展混淆意图char c -1; unsigned int u c; //c提升为int0xFFFFFFFF - 转换为unsigned int为4294967295 unsigned int u (unsigned char)c; //截断为0xFF2、溢出截断可借助0作为补码计算比如-700赋值给char-700256256256 68int a 50000; short b a; //若short为16位b值为-15536溢出3、类型提升导致正数小于负数unsigned int u 10; int s -5; if (u s) { //s被转换为unsigned int - 4294967291 }4、不同情况的整型提升unsigned int a1 9; unsigned int b1 1000; if (a1 - b1 1) //操作数精度相同则计算结果类型不变且中间过程无需转换 { printf(1 Hello world! %d\n, a1 - b1); } unsigned short a2 9; unsigned short b2 1000; if (a2 - b2 1) //低于int的在计算时不管需不需要都先统一到int { printf(2 Hello world! %d\n, a2 - b2); } unsigned int a6 9; unsigned int b6 1000; if (a6 - b6 -99) //常数的类型由变量类型决定 { printf(6 Hello world! %d\n, a6 - b6); }5、精度丢失float f 0.1f; double d 0.1; if (f ! d) { //因float精度不足实际存储值与double不同 } //建议避免直接比较浮点数使用误差范围 #define EPSILON 1e-6 if (fabs(f - d) EPSILON) { //近似相等 }

更多文章