【问题标题】:Unable to revert back to top of While loop无法返回到 While 循环的顶部
【发布时间】:2014-06-18 19:53:17
【问题描述】:

我是 C++ 新手,对我正在处理的问题有疑问。

我正在编写的程序旨在执行以下操作:

  1. 要求用户输入三角形 3 边的长度
  2. 检查 3 个边是否通过三角不等式定理(总和 任意两条边之和必须大于第三条边)
  3. 计算三角形的面积和周长

** 在第 2 步中,如果用户输入的边长违反了三角不等式定理,则要求她/他再次输入边长

例如,如果我输入边数:

  • 答:7
  • 乙:16
  • C: 10

我得到了所需的输出,并被提示输入另一组边长。但是,如果我输入以下内容:

  • 答:2
  • 乙:1
  • C: 1

然后我得到:

"三角形的面积为:-1.#IND
三角形的周长为:9"

“三角不等式定理被违反了。
请重新输入A边、B边和C边的长度。"

鉴于边 2、1、1,我正在尝试输出:

“三角不等式定理被违反了。
请重新输入A边、B边和C边的长度。"

...返回输入边长的提示。

我看不出我的代码哪里出了问题,希望有人能提供帮助。

这是我的代码:

#include "stdafx.h"
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;

void calculate(double& side_a, double& side_b, double& side_c);
void inputLengths(double& side_a, double& side_b, double& side_c);
bool isValid(double& side_a, double& side_b, double& side_c);

int _tmain(int argc, _TCHAR* argv[])
{
    double side_a = 3;
double side_b = 3;
double side_c = 3;

while (isValid(side_a, side_b, side_c) == true)
    {

    inputLengths(side_a, side_b, side_c);
    calculate(side_a, side_b, side_c);

    if (isValid(side_a, side_b, side_c) == false)
    {
        cout << "\n";
        cout << "The triangle inequality theorem has been violated." << endl;
        cout << "Please enter the lengths of side A, side B and side C again." << endl;
        continue;
    }
}
return 0 ;
}

void calculate(double& side_a, double& side_b, double& side_c)
{
double perimeter = side_a + side_b + side_c ;
double semiperimeter = (side_a + side_b + side_c) / 2 ;
double area = sqrt(semiperimeter * (semiperimeter - side_a) * (semiperimeter -     side_b) * (semiperimeter - side_c));

    cout << "\n";
    cout << "Given a triangle with the following side lengths:" << endl;
    cout << "\n"; 
    cout << "Side A: " << side_a << endl;
    cout << "Side B: " << side_b << endl;
    cout << "Side C: " << side_c << endl;
    cout << "\n";
    cout << "The area of the triangle is: " << area << endl;
    cout << "The perimeter of the triangle is: " << perimeter;
    cout << "\n";
}

void inputLengths(double& side_a, double& side_b, double& side_c)
{
cout << "\n";
cout << "Please enter the length of side A: ";
cin >> side_a;

cout << "Please enter the length of side B: ";
cin >> side_b;

cout << "Please enter the length of side C: ";
cin >> side_c;
} 

bool isValid(double& side_a, double& side_b, double& side_c)
{
// use the triangle inequality theorem to test that the sum of any two sides is
       greater than the third side
if ((side_a + side_b > side_c) && (side_a + side_c > side_b) && (side_b + side_c >
    side_a))
{
    return true;
}

else
{
    return false;
}
}

【问题讨论】:

  • 您要么 a) 从某个地方(或某人,又名同学)复制粘贴此代码,要么 b) 没有考虑太多。你的代码可以读作while the sides are valid ask for input and calculate perimeter, if invalid, output invalid message。相反,它显然应该是while user doesn't want to exit (ex: press Esc to exit), read input, if valid, calculate perimeter, OTHERWISE output invalid message
  • 一些额外的抱怨:1) 对于 IsValid(),不要通过引用传递。即使是意外,您实际上也不想更改值,因此按值传递。如果类型特别大(double 不是),则通过 const 引用传递。
  • 2) 将布尔值与真或假进行比较既奇怪又令人困惑。而不是“如果(b == true)”,只是“如果(b)”。同样,不是“if (b == false)”,而是“if (!b)”。

标签: c++ while-loop


【解决方案1】:

valid 变量代表isValid(side_a, side_b, side_c),其中只能在一个位置更新状态。

valid = true;
while (valid == true)      // <-- `continue`s here, checking condition
{
    valid = updateState(); // i.e. dependent upon `inputLengths`
    if (valid == false)
    {
        continue;
    }
    /* implicitly */ continue;
}

这显然代表了一个问题,因为代码说“当无效(或总是隐式地)但仅循环有效时继续”。

也就是说,循环在无效情况下被告知“继续”后立即结束 - 可以更改有效性的代码确实没有有机会再次执行。

相反,请考虑以下内容。

// Loop repeatedly until the user enters a "valid input" state
valid = false;
while (true) {             
     valid = readTriangleSides(); // Ask for the input; is it valid?
     if (!valid) {
        // Inform the user the input was invalid; implicit `continue`
     } else {
        // Valid, end the loop - this could be eliminated if the
        // loop was expressed as `while (!valid) ..`
        break;
     }
}

// Use the obtained values, now in the "valid input" state
calculateAndDisplay();

【讨论】:

    【解决方案2】:

    A=2,B=1,C=1 是一条长度为 2 的直线(因此是退化三角形),在这种情况下 A=B+C。

    当您在函数“isvalid”中测试您的值时:

    if ((side_a + side_b > side_c) && (side_a + side_c > side_b) && (side_b + side_c >
    side_a))
    

    你不认为这种情况是退化的情况(side_b+side_c=side_a)。因此,您必须将所有出现的“>”替换为“>=”,如下所示:

    if ((side_a + side_b >= side_c) && (side_a + side_c >= side_b) && (side_b + side_c >=
        side_a))
    

    【讨论】:

      【解决方案3】:

      我看到了自己的错误。我在检查有效性之前计算。对calculate() 的调用应该在while 循环中移到更低的位置。并且,应该有一个对 inputLengths() 的回调。代码应该是:

      int _tmain(int argc, _TCHAR* argv[])
      {
      double side_a = 3;
      double side_b = 3;
      double side_c = 3;
      
      while (isValid(side_a, side_b, side_c) == true)
      {
          inputLengths(side_a, side_b, side_c);
      
      
          if (isValid(side_a, side_b, side_c) == false)
          {
              cout << "\n";
              cout << "The triangle inequality theorem has been violated." <<
      endl;
              cout << "Please enter the lengths of side A, side B and side C
      again." << endl;
              inputLengths(side_a, side_b, side_c);
          }
      
          calculate(side_a, side_b, side_c);
      
      }
      return 0 ;
      }
      

      感谢大家的慷慨帮助。

      -伊丽莎白 C.

      【讨论】:

        猜你喜欢
        • 2015-07-01
        • 1970-01-01
        • 2016-07-12
        • 2021-08-17
        • 1970-01-01
        • 2019-07-03
        • 2023-03-31
        • 2015-11-17
        相关资源
        最近更新 更多