请协助:C ++中的“if”语句

时间:2013-04-22 05:02:08

标签: c++ if-statement conditional-statements

以下代码打印相同的结果 - 两次(!)(使用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

     

循环终止

7 个答案:

答案 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:

"This is the last remaining stronghold for the use of goto"

答案 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=500if,因为您正在修改循环变量;但如果改变条件,没有人会介意。它比添加一个标志更清洁,但仍然有点黑客。

答案 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 ++中,您的选择是......

  1. 使用goto而不是break。将目标标签放在最外面的循环之后。

  2. throw一个突破循环的异常,所有嵌套循环都嵌套在try块中。

  3. 根本不要打破循环。相反,请设置一个标记done或类似标记,以指示您何时完成。在所有循环的条件下检查它。

  4. 正如Jerry Coffin所说,使用将循环移动到一个单独的函数并使用return(不知道我错过了那个!)。

  5. 纯粹主义者可能更喜欢3,选项为2.特别是,唯一不打破结构化编程“单一退出原则”的选项是(3),但break也打破了这一原则无论如何。就个人而言,我更喜欢1,因为它产生的杂乱程度较低(如果您使用它的功能很小,goto在视觉上很明显),它更具可读性。

    通常可以避免使用goto,这是有充分理由的。很多人完全禁止它们,这是不合理的,但是那些人可能会认为breakcontinue是“隐藏的”并且也禁止它们(break除外{ {1}}语句,当然)。无论如何,你甚至可能不知道switch是可能的。

    goto here的语法描述 - 基本上是gotogoto <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.