c ++与双精度和整数的隐式转换混淆

时间:2018-02-21 21:45:23

标签: c++

我一直在研究c ++,我遇到了一个我不理解的隐式转换问题。在这段代码中:

#include <iostream>
using namespace std;
int main(){
    int i;
    i = 1 / 2 * 2 / 1. * 2. / 4 * 4;
    cout << i << endl;

    i = 3.5 + 2 + 1.6;
    cout << i << endl;

    i = 2 + 3.5 + 1.6;
    cout << i << endl;

    return 0;
}

输出分别为:0,7和7。

在最后两个例子中,编译器隐式地将元素转换为双精度数,因此sum = 7.1,然后将其转换为int以获得7。

因为第一个例子也有双打,所以我希望所有这些元素也被转换为双精度,并且总和为2.0,然后被强制转换为2,但结果为0,所以它似乎是“ 1/2“被视为整数,结果为0.我不确定这是编译器正在做什么,但这就是它的样子。

我认为如果任何元素是double,编译器会隐式地将所有元素转换为double。但是在第一种情况下不会发生这种情况。有人可以解释为什么编译器会以不同方式转换它们感谢。

2 个答案:

答案 0 :(得分:9)

  

我认为如果任何元素是double,编译器会隐式地将所有元素转换为double。尽管如此,这在第一种情况下并没有发生。

没有。编译器逐步解析表达式,而不是整体解析。对于

i = 1 / 2 * 2 / 1. * 2. / 4 * 4;

它被解析为i = ((1 / 2) * 2)...。在第一个括号中,只有int,因此应用了int算术,这导致了0.这个0使得整个表达式为0。

答案 1 :(得分:4)

C++ operator precedence and associativity中所述*(乘法)和/(除法)具有相同的优先级和从左到右的关联性。所以他们从左到右解析每个操作的结果类型根据rules逐个确定 - 注意那里的整体推广部分(注意评估顺序是不同的东西而不是直接如果您在那里有一个类型,那么整个表达式不会被提升为double。所以逻辑上这段代码:

i = 1 / 2 * 2 / 1. * 2. / 4 * 4;

等于:

auto a = 1 / 2; // a - int
auto b = a * 2; // b - int
auto c = b / 1.; // c - double
auto d = c * 2.; // d - double
auto e = d / 2;  // e - double
auto f = e * 4;  // f - double
i = f;

和每个变量a-f的类型分别确定。