• 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程序员。隐式类型转换在涉及原型的上下文中显得非常重要。

  • 相关阅读:
    挑战30天学完Python:Day2 夯实基础 - 变量和内置函数
    java计算机毕业设计原创网络文学管理系统源码+mysql数据库+系统+lw文档+部署
    P1278 单词游戏 简单搜索+玄学优化
    完美男人谢安游山玩水风流潇洒,东山再起以一敌十
    Python中的函数、闭包、装饰器、lambda表达式、生成器和递归
    布隆过滤器的优缺点及哈希切割问题
    蓝桥杯(3.6)
    Elasticsearch开启用户验证
    vim配置
    [python]pip安装requiements.txt跳过错误包继续安装
  • 原文地址:https://blog.csdn.net/weixin_40186813/article/details/126082982