//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;
}
当我运行这个程序时,我得到一个例外。
我放了一个断点,找到了问题的根源。
cin >> start >> tmn >> dis[start][tmn] >> cost[start][tmn],
但为什么我不能这样写呢?
答案 0 :(得分:3)
原因是,在部分陈述中
cin >> start >> tmn >> dis[start][tmn]
表达式start
,tmn
和dis[start][tmn]
的评估相对于彼此或对流operator>>()
的第一次调用没有排序
在调用阅读dis[start][tmn]
和operator>>()
的相关start
函数之前,一个可能的排序允许评估tmn
(以获取对数组元素的引用)。在这种情况下,start
和tmn
未初始化(因为它们的值尚未被读取)并且访问它们的值(评估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];
}
在尝试阅读start
和tmn
之前,检查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。