以下代码打印相同的结果 - 两次(!)(使用Microsoft Visual C ++ 2010 IDE)。我还打印了每个变量的最终值以查看发生了什么,并且实际上有两组值满足if
语句条件。
我的问题是因为指令是break;
如果条件评估为TRUE,任何人都可以解释我在没有要求的情况下如何/为什么我得到两个结果(不是这是一件坏事,只是试图了解)?这是if
构造的一部分还是与循环有关?如果条件不止一次地评估为TRUE,似乎有些人知道要返回多个解决方案,我只是不明白当指令没有明确说明这样做时它能够做到这一点(除非有一些内置的 - 在那我不知道)。
基本上,为什么一旦满足条件,循环就不会在break;
结束,或者我是否以错误的方式思考这个问题?
同样,如果有人知道或者我遗漏了一些基本的东西,请告诉我!我是C ++的新手,所以只是想学习,提前谢谢你。
以下是代码:
#include "stdafx.h"
#include <iostream>
int main()
{
for (int a = 1; a < 500; ++a)
{
for (int b = 1; b < 500; ++b)
{
for (int c = 1; c < 500; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << a*b*c << endl << "a = " << a << ", b = " << b << ", c = " << c << endl;
break;
}
}
}
}
cout << endl << "Loop terminated";
char d;
cin >> d;
return 0;
}
控制台输出如下:
产品abc = 31875000
a = 200,b = 375,c = 425
产品abc = 31875000
a = 375,b = 200,c = 425
循环终止
答案 0 :(得分:5)
您的break
仅突破内部循环,因此外循环继续执行。
一种可能性是将代码移动到单独的函数中,并在第一次找到匹配项时从函数返回。然后(除非你再次调用该函数)该代码的执行将完全停止。
我也完全消除了c
的循环。 c
唯一有意义的值是1000 - (a+b)
,因此您可以直接计算它而不是循环遍历500个不同的值来查找它。
答案 1 :(得分:0)
break
语句只会破坏最内层的循环,在休息的情况下你可能需要使用一个标志来退出其他循环
#include "stdafx.h"
#include <iostream>
int main()
{
bool flag = false;
for (int a = 1; a < 500; ++a)
{
for (int b = 1; b < 500; ++b)
{
for (int c = 1; c < 500; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << a*b*c << endl << "a = " << a << ", b = " << b << ", c = " << c << endl;
flag = true;
break;
}
}
if(flag)
{ break; }
}
if(flag)
{ break; }
}
cout << endl << "Loop terminated";
char d;
cin >> d;
return 0;
}
答案 2 :(得分:0)
你使用的break
只打破了大多数内部for
循环而不是所有循环。
使用标记并and
将其for
条件:
bool found = false;
for (int a = 1; a < 500 && !found; ++a)
{
for (int b = 1; b < 500 && !found; ++b)
{
for (int c = 1; c < 500 && !found; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << ....
found = true;
}
}
}
}
甚至您可以礼貌地使用goto
!
for (int a = 1; a < 500; ++a)
{
for (int b = 1; b < 500; ++b)
{
for (int c = 1; c < 500; ++c)
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << ...
goto break_all;
}
}
}
}
break_all:
答案 3 :(得分:0)
所以 - 你听说过break;
不是解决方案 - 但是它是什么?
如果你为每个循环设置一个变量的限制(目前为500),比如说
int myLim = 500;
用
替换每个for
循环条件
for (int a = 1; a < myLim; ++a)
{
for (int b = 1; b < myLim; ++b)
{
for (int c = 1; c < myLim; ++c)
{
然后代替break
你说myLim = -1
- 你将会突破所有循环。
注意 - 一些编译器会在满足a=500
条件时设置b=500
和if
,因为您正在修改循环变量;但如果改变条件,没有人会介意。它比添加一个标志更清洁,但仍然有点黑客。
答案 4 :(得分:0)
在您的代码中,您只应用了一次中断。因此,最内层的for循环将被破坏,其他外循环将继续。
所以你定义了flag变量来打破所有循环。
#include "stdafx.h"
#include <iostream>
int main()
{
bool flag = 0; //Set the flag
for (int a = 1; a < 500 && !flag; ++a) //Check flag condition
{
for (int b = 1; b < 500 && !flag; ++b) //Check flag condition
{
for (int c = 1; c < 500 && !flag; ++c) //Check flag condition
{
if ((a + b + c) == 1000 && ((a*a + b*b) == (c*c)))
{
cout << "The product abc = " << a*b*c << endl << "a = " << a << ", b = " << b << ", c = " << c << endl;
flag= 1; //Set the flag true
break;
}
}
}
}
cout << endl << "Loop terminated";
char d;
cin >> d;
return 0;
}
答案 5 :(得分:0)
正如许多人已经说过的那样,break
只会突破最内层的循环。
某些语言可以解决此问题。 Ada肯定有一种方法来命名每个循环,它最近的等价于break exit when <condition>;
,也可以写成exit <loopname> when <condition>;
。 IIRC C#也可能有特殊的语法。
在C ++中,您的选择是......
使用goto
而不是break
。将目标标签放在最外面的循环之后。
throw
一个突破循环的异常,所有嵌套循环都嵌套在try
块中。
根本不要打破循环。相反,请设置一个标记done
或类似标记,以指示您何时完成。在所有循环的条件下检查它。
正如Jerry Coffin所说,使用将循环移动到一个单独的函数并使用return
(不知道我错过了那个!)。
纯粹主义者可能更喜欢3,选项为2.特别是,唯一不打破结构化编程“单一退出原则”的选项是(3),但break
也打破了这一原则无论如何。就个人而言,我更喜欢1,因为它产生的杂乱程度较低(如果您使用它的功能很小,goto
在视觉上很明显),它更具可读性。
通常可以避免使用goto
,这是有充分理由的。很多人完全禁止它们,这是不合理的,但是那些人可能会认为break
和continue
是“隐藏的”并且也禁止它们(break
除外{ {1}}语句,当然)。无论如何,你甚至可能不知道switch
是可能的。
goto
here的语法描述 - 基本上是goto
和goto <labelname>;
。
答案 6 :(得分:0)
如果您尝试检查稍微更大的数字范围,您的代码将会非常慢。你实际上尝试c的所有值从1到500,并检查是否a + b + c = 1000.很明显,如果c = 1000 - a - b,则总和只有1000。所以你可以写
int c = 1000 - a - b;
if ((c >= 1 && c < 500) && (a*a + b*b == c*c)) ...
这将大约快500倍...
现在你不喜欢打印a = 200,b = 375和a = 375,b = 200。您可能会考虑一个break语句,但这会引入一个错误:在很多情况下,存在多个解决方案,这些解决方案并不像这里那样简单连接。
您想要的是避免打印解决方案,其中&gt; b,因为如果(a,b,c)是一个解,那么(b,a,c)也是一个解。一种简单的方法是编写
for (int b = a; b < 500; ++b) ...
当a = 375时,仅检查b的值375到499,这样可以避免打印a = 375,b = 200.