无明显类型的C表达式的评价

时间:2017-05-17 17:59:50

标签: c

从前一篇关于C的论文中考虑以下问题:

  

逐步显示如何评估以下C表达式,给出   表达式的值和该值的类型

9 / 3 / 2 * 6 + 2 * 1.5

类型是float还是double?有人可以澄清一下吗? (注意问题中没有明确的类型。)

4 个答案:

答案 0 :(得分:12)

根据通常的算术转换(6.3.1.8常规算术转换)

  

否则,如果任一操作数的相应实数类型为 double ,   另一个操作数在不更改类型域的情况下转换为a   相应实数类型为double的类型。

答案:

  1. 9/3 = 3(int)
  2. 3/2 = 1(int)
  3. 1 * 6 = 6(int)
  4. 2 * 1.5 = 3.0(双倍)
  5. 6 + 3.0 = 9.0(双倍)

答案 1 :(得分:5)

在您的表达式中1.5double(为了让编译器将其视为float,它应该有一个f后缀:1.5f) 。所有其他数字都是int类型。

为了展示如何评估9 / 3 / 2 * 6 + 2 * 1.5表达式,请查看C Operator Precedence以获取参考(优先级和关联性)。请注意,2 * 1.5的类型为double(因此整个表达式的类型)。

答案 2 :(得分:2)

这是double

正如Kernighan& amp; Ritchie的“C编程语言”:

  

浮点常量包含小数点(123.4)或指数(1e-2)或两者;他们的类型是双倍的,除非加上后缀。

快速找到自己的方法也就是编写代码: printf("%d %d\n", sizeof(1.5)==sizeof(double), sizeof(1.5)==sizeof(float)); 哪个会输出 1 0 表明1.5是双倍的。

编辑:当然,C中的类型大小取决于系统,因此代码不应完全受信任。

答案 3 :(得分:1)

这个问题也可以通过使用基于reflection的方法来解决。可以使用__builtin_types_compatible_p()将表达式的类型与float进行比较,然后使用double进行比较。此函数确定两种类型是否相同。为此,__typeof__可以方便地检索表达式的类型并将其传递给内置函数,如下所示:

#include <stdio.h>

int main() {
    if (__builtin_types_compatible_p(__typeof__(9 / 3 / 2 * 6 + 2 * 1.5), float)) {
        puts("float");
    } else if (__builtin_types_compatible_p(__typeof__(9 / 3 / 2 * 6 + 2 * 1.5), double)) {
        puts("double");
    }
    return (0);
}

请参阅demo

当类型相同时,函数返回1;查看更多here

注意:__typeof__不返回字符串,而是返回系统类型。

不是将整个数学表达式提供给 typeof ,而是可以简单地传递1.5,因为问题确实打开了什么数据类型代表这个浮点值。

参见相关信息:Syntax and Sample Usage of _Generic in C11