• C专家编程 第8章 为什么程序员无法分清万圣节和圣诞节 8.3 在等待时类型发生了变化


    在等待时类型发生了变化
    C语言中的类型转换比一般人想象的要广泛得多。在涉及类型小于int或double的表达式中,都有可能出现类型转换。以下面的代码为例: 
    printf(" %d ", sizeof 'A');
    这行代码打印出一个字符字面值类型的长度。你敢确定它的结果就是字符的长度,也就是1吗?你会发现事实上的结果是4(或者是你机器上int的长度),根据提升规则,它由char转换为int。 

    在表达式中,每个char都被转换为int...注意所有位于表达式中的float都被转换为double...由于函数参数也是一个表达式,所以当参数传递给函数时也会发生类型转换。具体地说,
    char和short转换为int,而float转换为double。
                                                                                               ---The C Programming Language 
    这个特性被称为类型提升。当它发生于整型类型时称为“整形提升”。ANSI C延续了自动类型提升的概念,尽管在许多地方它已褪色。 
    char c1, c2;
    /*...*/
    c1 = c1 + c2;
    “整形提升”规则要求抽象机器把每个变量的值提升为int的长度,然后对两个int值执行加法运算,然后再对运算结果进行裁剪。如果两个char的加法结果不会发生溢出异常,那么在实际执行时只需要产生char类型的运算结果,可以省略类型提升。 

    float f1, f2;
    double d;
    /*...*/
    f1 = f2 * d;
    如果编译器可以确定用float进行运算的结果跟转换为double后进行运算(例如,d由类型为double
    的常量2.0所代替)的结果一样,那么也可以使用float来进行乘法运算。

    常见类型提升的列表。他们可以出现在任何表达式中,并不局限于涉及操作符和混合类型操作
    数的表达式。
                  C语言中的类型提升
    源类型                        通常提升后的类型
    char、位段(bit-field)、枚举(enum)、unsigned char、short、unsigned short---> int
    (整型提升,前提是int能够完整地容纳原先的数据,否则将被转换为unsigned int。) 
    float --->double
    任何数组--->相应类型的指针
    ANSI C提到,如果编译器能够保证运算结果一致,也可以省略类型提升---这通常出现在表达式
    中存在常量操作数的时候。

    警惕!真正值得的注意之处---参数也会被提升
    另一个会发生隐式类型转换的地方就是参数传递。在K&R C中,由于函数的参数也是表达式,所以
    也会发生类型提升。在ANSI C中,如果使用了适当的函数原型,类型提升便不会发生。在被调用
    函数内部,提升后的参数被裁剪成原先声明的大小。
    这就是为什么单个printf()格式字符串%d能适用于几个不同类型,如short、char或int,而不论实际传递的是上述类型中的哪一个。函数从堆栈中(或寄存器中)取出的参数总是int类型,并在
    printf或其他被调用函数里按统一的格式处理。如果使用printf来打印比int长的类型如SunOS上的long long,就可以发现这个效果。除非使用long long格式化限定符%ld,否则无法获得正确的值。这是因为在缺少更多信息的情况下,printf假定它所处理的数据是int类型的。
    隐式类型转换方面,有3个重要的地方需要注意。
    *隐式类型转换是语言中的一种临机手段,起源于简化最初的编译器的想法。把所有的操作数转换
    成统一的长度极大地简化了代码的生成。这样,压到堆栈中的参数都是统一长度的,所以运行时
    系统只需要知道参数的数目,而不需要知道它们的长度。把所有的浮点数都以double精度进行就
    意味着PDP-11能够简单地设置为double运算模型,它只管按double精度执行运算,而无须顾忌操作数的精度。
    *即使不理睬缺省的类型转换,也可以用C语言进行大量的编程工作,许多C程序员就是这样做的。
    *在理解隐式类型转换这档子事之前,不能称自己是专家级C程序员。隐式类型转换在涉及原型的上下文中显得非常重要。

  • 相关阅读:
    pytest合集(9)— Hooks钩子函数
    全球首款 RISC-V 笔记本 ROMA 正式发布!
    深剖数商云B2B电商交易系统营销应用场景,赋能医疗器械企业实现精细化运营
    含文档+PPT+源码等]精品微信小程序ssm超市购物系统小程序+后台管理系统|前后分离VUE[包运行成功]微信小程序项目源码Java毕业设计
    问题(05)elementui 输入框里面禁止浏览器自动填充用户名密码、弹出浏览器历史密码提示框
    dart 学习 之 Getters and setters
    Fabric.js 自由绘制圆形
    老梗新玩「GitHub 热点速览 v.22.34」
    重邮803计网概述
    智慧公厕:革新性的公共厕所管理系统
  • 原文地址:https://blog.csdn.net/weixin_40186813/article/details/126082982