带有 for 循环的 goto() 函数
Posted
技术标签:
【中文标题】带有 for 循环的 goto() 函数【英文标题】:goto() function with for loops 【发布时间】:2020-09-12 11:01:28 【问题描述】:我正在制作一个简单的猜谜游戏,用户必须猜测隐藏地图(数组)中的一个关键位置,并且他有 12 次尝试进行猜测
我几乎成功了,但唯一的问题是计数器没有改变我希望TryCounter
在用户不猜测密钥位置时实际计算尝试次数
这是我的代码:
#include <iostream>
using namespace std;
int main()
bool w;
int x;
int y;
int array1[6][6] = 0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0;
cout << "game is starting ... " << endl;
cout << "You have 12 try to find one of the hidden keys " << endl;
loop: for (int TryCounter = 1; TryCounter <= 12; TryCounter++)
cout << " guess " << TryCounter << " - x and -y coordiants : " << endl;
cin >> x;
cin >> y;
if (TryCounter == 12)
cout << "You have used your chances" << endl;
if (w == false)
cout << "You lost" << endl;
for (int i = 0; i < 6; i++)//Drawing the hidden array
cout << " " << endl;
for (int j = 0; j < 6; j++)
cout << array1[i][j];
cout << " ";
break;
break;
for (int i = 0; i < 6; i++)//checking the input
for (int j = 0; j < 6; j++)
if (array1[x][y] == 1)
cout << "" << endl;
cout << "--- Nice Shot ! ---" << endl;
w = true;
cout << "You Won" << endl;
for (int i = 0; i < 6; i++) //drwaing the hidden map
cout << " " << endl;
for (int j = 0; j < 6; j++)
cout << array1[i][j];
cout << " ";
return 0;
else if (array1[x][y] == 0) //wrong guess
w = false;
cout << "--- You missed ---" << endl;
goto loop ;
【问题讨论】:
TryCounter
在 goto 标签之后被初始化。将int TryCounter = 1
移动到loop:
之前。
C++ 中没有“goto 函数”。 goto
是语言关键字,在 goto 语句中使用。
那我应该把它放在哪里呢?我尝试了几个位置,但都没有工作@i486
@Peter 对不起,我不知道我正在自学编程
不要投反对票。这是一个合理的问题,恕我直言。答案是,您可以删除循环标签和 goto。就如此容易。然后,让 for 循环包含带有检查的块。并删除if (TryCounter == 12)
检查。 for 循环已经为您做到了。
【参考方案1】:
通常人们会在没有 goto 的情况下进行编程。但有时确实有用……所以这里不做判断。
int main(...)
// the variable and array stuff...
for(int attemptCounter = 0; attemptCounter < 12; ++attemptCounter)
// the user input stuff...
// the checking if user guessed right
if( userGuessedCorrectly ) goto Success;
std::cout << "better luck next time, pal - you did not guess right." << std::endl;
return 0;
Success:
std::cout << "Congratulations you made it!" << std::endl;
return 0;
当然,在没有 goto 的情况下编写此代码会稍微困难一些。不过既然你想用,我就答应了。
【讨论】:
在没有goto
的情况下编写这个更容易。 goto
的使用混淆了这里实际发生的事情。使用goto
通常被认为是有害的,就像使用原始拥有指针被认为是有害的一样。这不是“不判断”的情况,好像这是个人选择。我们可以批评不良纪律而不“评判”一个人。在 C 中使用 goto
来清理代码有一些很好的论据;在 C++ 中使用 goto
没有什么好的理由。
@cdhowie 这取决于您应用的指标。在这种情况下如果没有 goto,当然我同意没有人会认真使用 goto,您需要将 for 循环的第一项移到外部,然后添加一个 if(attemptCounter < 12) ... else ...
,如果您应用“cyclometric复杂性”指标比 goto 更复杂。只是说...不是每个 goto 都是黑色的,也不是所有其他的都是白色的。 ;)
什么?您可以在示例代码中将goto Success;
替换为 std::cout << "Congratulations you made it!" << std::endl; return 0;
。您代码中的goto
实际上混淆了正在发生的事情。【参考方案2】:
查看您的代码,它看起来很复杂。 我试图通过重构来理解它,我希望你已经遇到了一些错误。
我的建议是从这段代码中提取一些函数。 我已经确定了一些重复的代码来将数组打印到 std::cout。 这将最深点上的循环嵌套减少了 2 个。
第二个功能是检查功能,您可以在其中检查镜头是否正常。 在这里,我注意到在循环中,您很可能错误地索引数组,因为您的循环使用 i 和 j(在循环中未使用),而您使用 x 和 y 进行索引。
提取后,您最终会得到一个 for 循环,您可以使用相同名称的关键字继续/中断该循环。 (这是我如何理解您的代码应该如何工作的想法https://compiler-explorer.com/z/TKqGMh)
我的经验法则是,如果你需要记住你的 for 循环的状态,这些应该被放入函数中。
【讨论】:
感谢您的重播,与您的代码相比,我的代码真是一团糟。 @JVApen 编辑:我运行了你的代码,看起来else if (array1[x][y] == 0) // wrong guess w = false; cout << "--- You missed ---" << endl;
不起作用,这总是一个胜利的局面。
就像我说的,我必须改变一些东西,因为我假设你有一个错误。但是,我认为总体要点很明确:在一个函数中放入一些东西以降低另一个函数的复杂性,从而使最终结果更易于维护【参考方案3】:
计数器不会因为您使用goto
而改变。计数器在循环结束时更改(右大括号)。你的执行指针永远不会到达右大括号,因为goto
将它提前隧道到循环的开头。
【讨论】:
以上是关于带有 for 循环的 goto() 函数的主要内容,如果未能解决你的问题,请参考以下文章
Oracle循环的几种写法(GOTO 、FOR 、 WHILE 、LOOP)
Linux C 编程学习第四天_循环语句_while_do/while_for_goto
C语言基础:循环结构(循环类型(while,do...while,for,嵌套循环),循环控制语句(break,continue,goto),无线循环(死循环))