如何修复 - 控件可能会到达非空函数的末尾

how to fix- Control may reach end of non-void function

我在cs50的时候遇到问题class,我不得不写二分查找功能。 尝试 运行 编码时出现此消息:control may reach end of non-void function。我试图通过在最后一行添加 return false 来修复,但这使得输出总是 false。请给我一些提示。

这是我的代码:

bool search_r(int value, int values[], int l, int r) {
    int v = values[(l + r) / 2];
    int right = r;
    int left = l;
    if ((l + r) / 2 > 0) {
        if (v == value) {
            return true;
        } else 
        if (v > value) {
            right = ((l + r) / 2);
            search_r(value, values, left, right);
        } else
        if (v < value) {
            left = ((l + r) / 2);
            search_r(value, values, left, right);
        }
    } else {
        return false;
    }         
}

最后的else不是必需的,如果你只是returnfalse它就会完全按照你的要求去做。但是您可能应该 return trueif 分支内。或者使该函数根本不是 return,因为无论如何您都没有使用 return 值,如果它始终是 false,它也不是很有用。

考虑不满足 if 条件的情况,程序在不给出 return 值的情况下结束。现在这是不可能的,因为你的 else condition.But 编译器不知道这一点,因此想要确保函数 return 是一个值,因为它是一个非空函数。 删除 else 条件并简单地添加

return false;

在你的程序结束时将解决问题。

你的函数有几个问题:

  • 您必须 return 来自对 search_r() 的递归调用的值。此错误导致警告,因为该函数在嵌套的 if 语句之后没有 return 语句。在末尾设置 return false; 是不正确的,因为如果找到 value,递归调用应该 return true
  • 如果 lr 非常大,
  • (l + r) / 2 可能会溢出。在这种情况下,结果将是不正确的。计算中间索引的正确方法是 l + (r - l) / 2.
  • 终止测试不是(l + r) / 2 > 0,它只测试中间索引是否是> 0。而是使用 l < r,即。如果范围不为空,则包含 l 并排除 r
  • 测试 if (v < value) 是多余的,您已经测试了 v == valuev > value
  • 使用 l 作为变量名有点令人困惑,因为它在视觉上与 1 非常相似,尤其是对于用于代码的固定间距字体。

这是更正后的版本:

bool search_r(int value, int values[], int left, int right) {
    if (left < right) {
        int middle = left + (right - left) / 2;
        int v = values[middle];
        if (v == value) {
            return true;
        } else
        if (v > value) {
            return search_r(value, values, left, middle);
        } else {
            return search_r(value, values, middle + 1, right);
        }
    } else {
        return false;
    }
}

最后,该函数可以作为一个循环来实现,而不是使用递归。编译器很可能生成相同的代码,因为递归是终止的,但有些人发现一种方式比另一种方式更直观:

bool search_r(int value, int values[], int left, int right) {
    while (left < right) {
        int middle = left + (right - left) / 2;
        int v = values[middle];
        if (v == value) {
            return true;
        } else
        if (v > value) {
            right = middle;
        } else {
            left = middle + 1;
        }
    }
    return false;
}

在这两种情况下,函数都应该这样调用,其中lengtharray的元素个数。

bool found = search_r(value, array, 0, length);

你的函数:

bool search_r(int value, int values[], int left, int right)

表示将返回一个bool。我认为@chqrlie 对此有很好的回应。

您应该返回一些不受任何循环或条件影响的默认值,以防不满足这些条件。