携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情
类型转换的规则
- 当类型转换出现在表达式时,无论是unsigned还是signed的char和short都会被自动转换成int,如有必要会被转换unsigned int。
- 涉及两种类型的运算,两个值会被分别转换两种类型的更高级别。
- 类型的级别从高到低依次是long double,double,float,unsigned long long,long long,unsigned long,long,unsigned int,int。例外的是:当long和int的大小相同时,unsigned int比long的级别高。之所以short和char类型没有列出,是因为它们已经被升级到int或unsigned int。
- 在赋值表达式语句中,计算的最终结果会被转换成被赋值变量的类型。
- 当作为函数参数传递时,char和short被转换成int,float被转换成double。
当待转换的值与目标类型不匹配时
待赋值的值与目标类型不匹配时,规则如下:
- 目标类型是无符号整型,且待赋值的值是整数时,额外的位将被忽略。例如,如果目标是8位unsigned char,待赋值是原始值求模256.
- 如果目标类型是一个有符号整型,且待赋值的值是整数,结果因实现而异。
- 如果目标类型是一个整形,且待赋值是浮点数,该行为未被定义的。
当浮点类型被降级为整数类型时,原来的浮点值会被截断。例如下面例子:
举一个例子
#include <stdio.h>
void pound(int n); //ANSI函数原型声明
int main(){
char ch;
int i;
float f1;
f1=i=ch='C'; //第9行
printf("ch=%c,i=%d,f1=%2.2f\n",ch,i,f1); //第10行
ch=ch+1; //第11行
i=f1+2*ch; //第12行
f1=2.0*ch+1; //第13行
printf("ch=%c,i=%d,f1=%2.2f\n",ch,i,f1); //第14行
ch = 1107; //第15行
printf("Now ch=%c\n",ch); //第16行
ch=80.89; //第17行
printf("Now ch=%c\n",ch); //第18行
return 0;
}
运行结果
分析一下
- 第9行和第10行:字符‘C’被作为1字节ASCII值存储在ch中。整形变量i接受由‘C’转换的整数,即按4字节存储67.最后,f1接受由67转换的浮点数67.00.
- 第11行和第14行:字符变量‘C’被转换成整数67,然后加1.计算结果是4字节整数68,被截断成1字节存储在ch中。根据%c转换说明打印时,68被解释成‘D’的ASCII码。
- 第12行和第14行:ch的值被转换成4字节的整数(68),然后2乘以ch。为了和f1相加,乘积整数(136)被转换成浮点数。计算结果(203.00f)被转换成int类型,被储存到i中。
- 第13行和第14行:ch的值(‘D’,或68)被转换成浮点数,然后2乘以ch。为了做加法,i的值(203)被转换为浮点类型。计算结果(339.00)被储存f1中。
- 第15行和第16行:演示了类型降级的示例。把ch设置为一个超出其类型范围的值,忽略额外的位后,最终ch的值是字符S的ASCII码。更确定的说,ch的值是1107%265,即83.
- 第17行和第18行:演示了另一个类型降级的实例。把ch设置为一个浮点数,发生截断后,ch的值是字符P的ASCII。