C ++ - 奇怪的是,输入被颠倒了

时间:2014-03-06 08:38:24

标签: c++ input output

我发现了一些奇怪的东西,我测试了这段代码:

#include <iostream>
using namespace std;

int main() {
    int i=0, a[5];
    cin>>a[i++]>>a[i++]>>a[i++];
    for(int j=0; j<i; j++){
        cout<<a[j]<<endl;
    }
}

使用此输入:

1
2
3

并将输入反转为:

3
2
1

我认为它的输出应与此代码相同:

#include <iostream>
using namespace std;

int main() {
    int i=0, a[5];
    cin>>a[i++]; cin>>a[i++]; cin>>a[i++];
    for(int j=0; j<i; j++){
        cout<<a[j]<<endl;
    }
}

以前有人经历过这个吗?感谢。

- 编辑 -

感谢大家的回答!

5 个答案:

答案 0 :(得分:9)

这感觉就像未定义的行为和编译器相关:

cin>>a[i++]>>a[i++]>>a[i++];

(主人,如果我错了,请纠正我)

答案 1 :(得分:9)

语句cin>>a[i++]>>a[i++]>>a[i++];的行为实际上是 undefined 。这是因为没有序列点

您不知道i何时会增加,因此您的输出并不令人惊讶。

请参阅http://en.wikipedia.org/wiki/Sequence_point

答案 2 :(得分:5)

cin>>a[i++]>>a[i++]>>a[i++];

只是

的语法糖
cin.operator>>(a[i++]).operator>>(a[i++]).operator>>(a[i++]);

现在,三个调用operator>>肯定是从左到右执行,但是三个参数 {{1可以按任何顺序评估。让我们调用参数a[i++]xy

z

您可能希望编译器替换cin.operator>>(x).operator>>(y).operator>>(z); xy,如下所示:

z

但实际上,编译器可以提供更多自由。在您的情况下,它选择:

int& x = a[i];
i++;
int& y = a[i];
i++;
int& z = a[i];
i++;

正如詹姆斯坎泽指出的那样,它也可以选择:

int& z = a[i];
i++;
int& y = a[i];
i++;
int& x = a[i];
i++;

答案 3 :(得分:2)

在同一语句中修改和使用变量时,会导致未定义的行为。 我被修改了3次,并在下面的声明中访问了3次。

cin>>a[i++]>>a[i++]>>a[i++];

我想下面的代码可以正常工作。

#include <iostream>
using namespace std;
int main() {
    int i=0, a[5];
    cin>>a[0]>>a[1]>>a[2];

    i=3;

    for(int j=0; j<i; j++){
    cout<<a[j]<<endl;
}
}

答案 4 :(得分:1)

正如已经说过的那样,代码具有未定义的行为,因为函数参数的评估顺序没有被指定,因此后增量运算符的副作用的结果不会以确定的方式排序。

然后我将解释结果。

表达

cin>>a[i++]>>a[i++]>>a[i++];
如果我们将使用功能符号

等同于以下表达式

cin.operator >>( a[i++] ).operator >>( a[i++] ).operator >>( a[i++] );

未指定函数参数的评估顺序。因此,一些编译器会从右到左评估参数,而其他编译器则从左到右。

很明显,您的编译器从右到左评估函数参数。第一个是评估最右边函数的参数

cin.operator >>( a[i++] ).operator >>( a[i++] ).operator >>( a[0] );

在评估参数后,编译器应用副作用。我变得等于1.然后编译器评估第二个函数的参数,你得到

cin.operator >>( a[i++] ).operator >>( a[1] ).operator >>( a[0] );

最后在评估第一个函数调用的参数后会有

cin.operator >>( a[2] ).operator >>( a[1] ).operator >>( a[0] );

和变量i将等于3。

然而,正如我所说的函数参数的评估顺序也未指定,其他编译器可以将此表达式表示为

cin.operator >>( a[0] ).operator >>( a[1] ).operator >>( a[2] );

因此结果可能不同,程序的行为未定义。