在循环中跟踪当前和先前的变量
Keeping track of current and previous variables in a loop
我的程序中有一个错误,我发现 非常 令人困惑。
下面是有问题的代码的最小版本,用于重现我的错误。
#include <iostream>
struct derp
{
int idx;
};
int main (int argc, char **argv)
{
derp initial;
initial.idx = 0;
derp *prev = &initial;
while (true)
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
{
}
if (c == EOF)
{
break;
}
derp cur;
cur.idx = prev->idx + 1;
std::cerr << "Prev: " << prev->idx << ", cur: " << cur.idx << std::endl;
prev = &cur;
}
}
另存为wtf.cpp
。
编译。
$ CC wtf.cpp
运行.
$ (echo;echo;echo) | ./a.out
预期输出:
Prev: 0, cur: 1
Prev: 1, cur: 2
Prev: 2, cur: 3
运行时的实际输出:
Prev: 0, cur: 1
Prev: 2, cur: 2
Prev: 3, cur: 3
我在 Sun Solaris 10 10/09 s10x_u8wos_08a X86 上使用来自 Oracle Solaris Studio 12.4 的 CC。
prev 是一个指针,它最初指向一个变量,该变量在整个 while 循环中保持其作用域。然后在 while 循环中,您创建一个新变量 'cur',其范围限于该次迭代,并保存指向该临时变量的指针。尝试在 while 循环之外定义 cur。
干杯!
问题是您的代码使用了超出范围的指针。一旦进入下一次迭代,任何对 cur
的引用在循环的先前迭代中有效都将无效。这就是为什么当 prev
指向 initial
时,第一次迭代是代码按预期工作的唯一迭代。在随后的迭代中,prev
恰好指向与 cur
相同的位置,因为编译器在循环的所有迭代中将它保持在相同的位置。但是,该行为是未定义的,因此在使用其他编译器编译时可能会得到不同的结果。
你需要在循环外同时声明prev
和cur
,并复制整个结构,像这样:
derp prev;
prev.idx = 0;
derp cur;
while (true) {
int c;
while ((c = getchar()) != '\n' && c != EOF)
{
}
if (c == EOF)
{
break;
}
cur.idx = prev.idx + 1;
std::cerr << "Prev: " << prev.idx << ", cur: " << cur.idx << std::endl;
prev = cur;
}
我的程序中有一个错误,我发现 非常 令人困惑。
下面是有问题的代码的最小版本,用于重现我的错误。
#include <iostream>
struct derp
{
int idx;
};
int main (int argc, char **argv)
{
derp initial;
initial.idx = 0;
derp *prev = &initial;
while (true)
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
{
}
if (c == EOF)
{
break;
}
derp cur;
cur.idx = prev->idx + 1;
std::cerr << "Prev: " << prev->idx << ", cur: " << cur.idx << std::endl;
prev = &cur;
}
}
另存为wtf.cpp
。
编译。
$ CC wtf.cpp
运行.
$ (echo;echo;echo) | ./a.out
预期输出:
Prev: 0, cur: 1
Prev: 1, cur: 2
Prev: 2, cur: 3
运行时的实际输出:
Prev: 0, cur: 1
Prev: 2, cur: 2
Prev: 3, cur: 3
我在 Sun Solaris 10 10/09 s10x_u8wos_08a X86 上使用来自 Oracle Solaris Studio 12.4 的 CC。
prev 是一个指针,它最初指向一个变量,该变量在整个 while 循环中保持其作用域。然后在 while 循环中,您创建一个新变量 'cur',其范围限于该次迭代,并保存指向该临时变量的指针。尝试在 while 循环之外定义 cur。
干杯!
问题是您的代码使用了超出范围的指针。一旦进入下一次迭代,任何对 cur
的引用在循环的先前迭代中有效都将无效。这就是为什么当 prev
指向 initial
时,第一次迭代是代码按预期工作的唯一迭代。在随后的迭代中,prev
恰好指向与 cur
相同的位置,因为编译器在循环的所有迭代中将它保持在相同的位置。但是,该行为是未定义的,因此在使用其他编译器编译时可能会得到不同的结果。
你需要在循环外同时声明prev
和cur
,并复制整个结构,像这样:
derp prev;
prev.idx = 0;
derp cur;
while (true) {
int c;
while ((c = getchar()) != '\n' && c != EOF)
{
}
if (c == EOF)
{
break;
}
cur.idx = prev.idx + 1;
std::cerr << "Prev: " << prev.idx << ", cur: " << cur.idx << std::endl;
prev = cur;
}