关于cin和>>令人困惑的事情C ++

时间:2018-06-03 02:35:43

标签: c++ cin

//win10 vs2017
#include<iostream>
using namespace std;
typedef unsigned int uint;
uint dis[1002][1002];
uint cost[1002][1002];
uint v, e;
int main()
{
    while (cin >> v, v) {
        cin >> e;
        int start, tmn;
        for (int i = 0; i < e; i++)
            cin >> start >> tmn >> dis[start][tmn] >> cost[start][tmn], dis[tmn][start] = dis[start][tmn], cost[tmn][start] = cost[start][tmn];
        cin >> start >> tmn;
    }

    system("pause");
    return 0;
}

当我运行这个程序时,我得到一个例外。

enter image description here

我放了一个断点,找到了问题的根源。

cin >> start >> tmn >> dis[start][tmn] >> cost[start][tmn],

但为什么我不能这样写呢?

2 个答案:

答案 0 :(得分:3)

原因是,在部分陈述中

cin >> start >> tmn >> dis[start][tmn]

表达式starttmndis[start][tmn]的评估相对于彼此或对流operator>>()的第一次调用没有排序

在调用阅读dis[start][tmn]operator>>()的相关start函数之前,一个可能的排序允许评估tmn(以获取对数组元素的引用)。在这种情况下,starttmn未初始化(因为它们的值尚未被读取)并且访问它们的值(评估dis[start][tmn]所必需的)会给出未定义的行为。

解决方案(这也有助于使代码对人类更具可读性)是避免依赖于(或在您的情况下,错误地假设)特定评估顺序的复杂表达式。

而不是(blech!)

for (int i = 0; i < e; i++)
     cin >> start >> tmn >> dis[start][tmn] >> cost[start][tmn],
         dis[tmn][start] = dis[start][tmn], cost[tmn][start] = cost[start][tmn];

(我将语句分成两行)将输入语句分解为单独的语句 - 它们将相对于彼此排序 - 并避免使用,运算符来实现其他效果言。

for (int i = 0; i < e; i++)
{
    cin >> start >> tmn;
    cin >> dis[start][tmn] >> cost[start][tmn];

    dis[tmn][start] = dis[start][tmn];
    cost[tmn][start] = cost[start][tmn];
}

在尝试阅读starttmn之前,检查dis[start][tmn]cost[start][tmn]是否有效可能也是一个好主意。

虽然您没有被问到这个问题,while (cin >> v, v)可能也没有按照您的想法行事。

答案 1 :(得分:-2)

输入序列必须是&gt;&gt;'start',然后是&gt;&gt;'dis [start] [tmn]',但也许编译器优化'dis [start] [tmn]'作为int&amp ;.因此在输入之前,'dis [start] [tmn]'被视为int&amp;,从而导致错误 这是assembly code 请参阅Bjarne Stroustrup主页的evaluation order