【问题标题】:How to break out of a loop in C如何打破C中的循环
【发布时间】:2013-01-30 10:24:59
【问题描述】:

我正在编写一个二分法算法来查找多项式的根。我的代码的第二部分说如果变量FP 等于零或b-a 的绝对值它只是打破了我猜的if 语句。

我希望程序完全停止 for 循环(迭代)并返回 p。最后,我想打印获得解决方案所需的迭代次数,但显然使用我的 printf 语句它表明即使获得了根(零),程序也会继续执行。

关于如何停止整个机制并返回 p 的值为零和它所花费的确切迭代次数的任何想法?谢谢

double computeroots(double a, double b, double epsilon, int MaxIter)
{
    double FA = pow(a,4) -4*a +  1;
    double FB = pow(b,4) - 4*b + 1;
    double FP;
    double p;
    int i;

    for(i=0;i<MaxIter;i++) {
        if(FA * FB < 0) {
            p = a + (b-a)/2;
            FP = pow(p,4) - 4*p +1;
            if(FP == 0 || abs(b-a) < epsilon) {
                return p;
                break;
            } else if (FA * FP >0) {
                a =p;
                FA = FP;
            } else {
                b = p;
                FB = FP;
            }
            i++;
        }
    }

    printf("The number of iterations is: %d\n", i);
}

【问题讨论】:

  • 我没有更改您的标题,但这绝对是一种误导。您只有一个循环,而不是外部循环和嵌套循环。
  • 您将 i 增加了两次,因此您只运行了一半的迭代。

标签: c loops break bisection


【解决方案1】:

您的printf 语句未命中,因为您在break 语句之前有一个return p;。 return 语句立即退出函数。

您需要将return语句移到printf之后,或者将printf移到return之前:

        if(FP == 0 || abs(b-a) < epsilon)
        {
            printf("the number of iterations is : %d\n", i);
            return p;
        }
        ...

    printf("failed to converge after %d iterations\n", i);
    return p;
}

【讨论】:

  • 或者,将中断留在原处并将return 移动到函数的末尾(它所属的位置!)
【解决方案2】:

如果你有一个return 语句,那么你的break 语句是没用的。 return 退出函数的作用域并返回给调用者,因此之后不再执行任何指令。

所以这个:

return p;
break;

应该变成:

printf("the number of iterations is : %d\n", i);
return p;

如果您发现退出条件选择不正确,我猜这更像是一个有限精度问题。您正在检查FP == 0,但FP 是double,因此当FP 足够接近0 而不是完全相等时,您必须停止。例如:abs(FP) &lt; epsilon.

【讨论】:

    【解决方案3】:

    当您需要返回多个值时,您可以使用 out-arguments 来实现。将您的功能更改为

    double computeroots(double a, double b, double epsilon, int MaxIter, int *numIterations)
    

    这样称呼它:

    int numIter;
    soln = computeroots(a, b, epsilon, MaxIter, &numIter);
    

    在你的函数中,在返回之前,添加:

    *numIterations = i;
    

    【讨论】:

    • 感谢阿德里安,您挽救了这一天。但我不明白的是,您是说 computeroots 应该期望一个指向名为 numIterations 的整数的指针,对!到目前为止一切都很好,当你调用它时,你使用与号也很好,因为它是一个指针。但令人困惑的是,你将 numIterations 声明为整数而不是指向整数的指针。很好,但我还是很困惑,我们应该在 main 中声明它 int *numIterations 而不仅仅是 int numIterations
    • 另外,当我想在 printf 中显示 numIterations 的值时,它返回了不兼容的警告。我说 printf(".....", *numIterations);这是错误的我知道不应该有星号,但我不明白为什么。由于它是一个指针,它应该在它之前获得星号以便返回它指向的值。没有星号,它应该返回它指向的变量的地址而不是值......请任何解释
    • 它不是指针。这是一个普通的整数,你通过引用函数来传递它:& 可以翻译为“...的内存方向”。因此,在您使用 * 的函数内部(这是间接运算符,您可能会发现将其翻译为“内存方向的内容......”很有用)。您可以使用普通变量的内存引用,它们不一定是指针。
    • 您需要通过引用传递参数(使用 &),否则函数将无法修改外部变量的值(仅局部变量,在函数内部声明或全局变量)。
    【解决方案4】:

    合并所有必要的修改:

    double computeroots(
      double a, 
      double b, 
      double epsilon, 
      size_t MaxIter, 
      size_t * pNumIter
    ) 
    {
        double FA = pow(a,4) -4*a +  1;
        double FB = pow(b,4) - 4*b + 1;
        double FP;
        double p = NaN;
        size_t i;
    
        for(i=0; i<MaxIter; ++i) {
            if(FA * FB < 0) {
                p = a + (b-a)/2;
                FP = pow(p,4) - 4*p +1;
                if(FP == 0 || abs(b-a) < epsilon) {
                    break;
                } else if (FA * FP >0) {
                    a =p;
                    FA = FP;
                } else {
                    b = p;
                    FB = FP;
                }
            }
        }
    
        *pNumIter = i;
    
        printf("the number of iterations is : %z\n", *pNumIter);
    
        return p;
    }
    

    这样称呼它:

    double a, b, epsilon;
    size_t sizeMax, sizeIterations;
    
    ... /* some initialisations here */
    
    double d = computeroots(a, b, epsilon, sizeMax, &sizeIterations);
    

    修改说明:

    • 删除错位return
    • 在末尾添加了缺少的返回
    • 将ints 更改为size_t,因为unsigned 类型更适合柜台
    • 添加了对附加 size_t 变量的引用以返回迭代次数
    • 删除了i 的第二个增量

    【讨论】:

    • 什么是"mods/s"? “修改”?
    【解决方案5】:

    您可以返回一个双精度数组,其中第一个元素是结果,第二个元素是迭代次数。

    或者,您将变量的引用传递给函数,然后分配给它,如下所示:

    double compute_something(int param1, int param2, int* iterations) {
        // your code ...
        // when you want to return, use this:
        *iterations = 5;
        return 1.23;
        // your code ...
    }
    
    int iter;
    double result = compute_something(1,2, &iter);
    

    在此之后,result 包含结果,并且 iter 是您存储的迭代次数。 此解决方案可能会更好,因为您没有将迭代次数(显然是整数)返回为双精度数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多