我发现了一些奇怪的东西,我测试了这段代码:
#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;
}
}
以前有人经历过这个吗?感谢。
- 编辑 -
感谢大家的回答!
答案 0 :(得分:9)
这感觉就像未定义的行为和编译器相关:
cin>>a[i++]>>a[i++]>>a[i++];
(主人,如果我错了,请纠正我)
答案 1 :(得分:9)
语句cin>>a[i++]>>a[i++]>>a[i++];
的行为实际上是 undefined 。这是因为没有序列点。
您不知道i
何时会增加,因此您的输出并不令人惊讶。
答案 2 :(得分:5)
cin>>a[i++]>>a[i++]>>a[i++];
只是
的语法糖cin.operator>>(a[i++]).operator>>(a[i++]).operator>>(a[i++]);
现在,三个调用到operator>>
肯定是从左到右执行,但是三个参数 {{1可以按任何顺序评估。让我们调用参数a[i++]
,x
和y
:
z
您可能希望编译器替换cin.operator>>(x).operator>>(y).operator>>(z);
,x
和y
,如下所示:
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] );
因此结果可能不同,程序的行为未定义。