如何修复 - 控件可能会到达非空函数的末尾
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 true
在 if
分支内。或者使该函数根本不是 return,因为无论如何您都没有使用 return 值,如果它始终是 false
,它也不是很有用。
考虑不满足 if 条件的情况,程序在不给出 return 值的情况下结束。现在这是不可能的,因为你的 else condition.But 编译器不知道这一点,因此想要确保函数 return 是一个值,因为它是一个非空函数。
删除 else 条件并简单地添加
return false;
在你的程序结束时将解决问题。
你的函数有几个问题:
- 您必须 return 来自对
search_r()
的递归调用的值。此错误导致警告,因为该函数在嵌套的 if
语句之后没有 return
语句。在末尾设置 return false;
是不正确的,因为如果找到 value
,递归调用应该 return true
。
如果 l
或 r
非常大,(l + r) / 2
可能会溢出。在这种情况下,结果将是不正确的。计算中间索引的正确方法是 l + (r - l) / 2
.
- 终止测试不是
(l + r) / 2 > 0
,它只测试中间索引是否是> 0
。而是使用 l < r
,即。如果范围不为空,则包含 l
并排除 r
。
- 测试
if (v < value)
是多余的,您已经测试了 v == value
和 v > 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;
}
在这两种情况下,函数都应该这样调用,其中length
是array
的元素个数。
bool found = search_r(value, array, 0, length);
你的函数:
bool search_r(int value, int values[], int left, int right)
表示将返回一个bool。我认为@chqrlie 对此有很好的回应。
您应该返回一些不受任何循环或条件影响的默认值,以防不满足这些条件。
我在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 true
在 if
分支内。或者使该函数根本不是 return,因为无论如何您都没有使用 return 值,如果它始终是 false
,它也不是很有用。
考虑不满足 if 条件的情况,程序在不给出 return 值的情况下结束。现在这是不可能的,因为你的 else condition.But 编译器不知道这一点,因此想要确保函数 return 是一个值,因为它是一个非空函数。 删除 else 条件并简单地添加
return false;
在你的程序结束时将解决问题。
你的函数有几个问题:
- 您必须 return 来自对
search_r()
的递归调用的值。此错误导致警告,因为该函数在嵌套的if
语句之后没有return
语句。在末尾设置return false;
是不正确的,因为如果找到value
,递归调用应该 returntrue
。
如果 (l + r) / 2
可能会溢出。在这种情况下,结果将是不正确的。计算中间索引的正确方法是l + (r - l) / 2
.- 终止测试不是
(l + r) / 2 > 0
,它只测试中间索引是否是> 0
。而是使用l < r
,即。如果范围不为空,则包含l
并排除r
。 - 测试
if (v < value)
是多余的,您已经测试了v == value
和v > value
。 - 使用
l
作为变量名有点令人困惑,因为它在视觉上与1
非常相似,尤其是对于用于代码的固定间距字体。
l
或 r
非常大,这是更正后的版本:
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;
}
在这两种情况下,函数都应该这样调用,其中length
是array
的元素个数。
bool found = search_r(value, array, 0, length);
你的函数:
bool search_r(int value, int values[], int left, int right)
表示将返回一个bool。我认为@chqrlie 对此有很好的回应。
您应该返回一些不受任何循环或条件影响的默认值,以防不满足这些条件。