C语言的类型转换

257 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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;
}

运行结果

Snipaste_2022-08-15_21-00-11.png

分析一下

  • 第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。