如何解决什么时候从函数返回?
如果问题听起来很幼稚,请提前抱歉。我正在编写一个简单的布尔函数,以检查数字的所有数字是否相同。以下作品,但是之后的作品,给我一个错误
17:1: warning: control reaches end of non-void function [-Wreturn-type]
第二个我做错了什么?
工作:
# include <iostream>
# include <string>
using namespace std;
bool samedigits (int number){
bool result = true;
std::string snumber = to_string (number);
for (int i=0; i < snumber.size(); i++){
if (snumber[i] != snumber[0]){
result = result and false;
break;
}
}
return result;
}
int main()
{
cout << samedigits (666);
return 0;
}
不工作:
# include <iostream>
# include <string>
using namespace std;
bool samedigits (int number){
std::string snumber = to_string (number);
for (int i=0; i < snumber.size(); i++){
if (snumber[i] != snumber[0]){
return false;
break;
}
return true;
}
}
int main()
{
cout << samedigits (666);
return 0;
}
解决方法
您的算法不正确,您仅检查第一个字符是否等于其自身,并为每个输入返回true。相反,您应该将try {
$t = [IO.File]::ReadAllText($f,[Text.Encoding]::GetEncoding(65001,`
(New-Object Text.EncoderExceptionFallback),`
(New-Object Text.DecoderExceptionFallback)))
} catch {
# File is not UTF-8,reopen as Shift-JIS
$t = [IO.File]::ReadAllText($f,[Text.Encoding]::GetEncoding(932))
}
# Write the file as UTF-8
[IO.File]::WriteAllText($f,$t)
移到循环之外,以便首先检查所有字符。
不幸的是,警告是误报。编译器未能意识到在传递return true
时,保证std::to_string
返回一个非空字符串。这意味着将输入int
循环主体,并且该函数将返回一个值。
编译器是正确的。您的第二个代码段中有一个不会返回的代码路径。
npm i --save-dev @typescript-eslint/parser
在这里,for (int i=0; i < snumber.size(); i++){
大小函数可以根据其约定返回std::string
。当它发生时,您的函数将不会进入循环。之后,您不返回就退出函数。
函数的第二个版本(结合一些通过注释获得的信息)表明对return
的功能存在误解。如果return
语句只是存储指示的值以在函数最终结束时使用,则第二个版本将起作用(这是误解)。但是,这不是return
的工作方式。 return
语句存储指示的值,以在函数结束并立即结束函数时使用。在函数的第二个版本中,for
语句也可能是if
,并且break
永远不会执行,因为它紧随return
之后。
为演示,让我们进行一次代码遍历,以调用samedigits(123)
。
bool samedigits (int number){
当我们输入函数时,number
被设置为123
。
std::string snumber = to_string (number);
字符串snumber
设置为"123"
。
for (int i=0; i < snumber.size(); i++){
通过将i
设置为0
来初始化循环,然后检查是否0 < 3
(snumber
的大小为3)。这是真的,所以我们进入循环。请注意,进入循环的结果仅取决于snumber
是否为空。
if (snumber[i] != snumber[0]){
我们检查snumber[0]
是否不等于snumber[0]
。这有点琐碎,但是计算机愿意这样做。结果当然是错误的(与输入内容无关–如果循环从1
而不是0
开始,这部分可能会更有趣)。因此,请跳到if
之后的语句。
return true;
函数立即结束,返回true
。
就是这样。没有循环的第二次迭代。在此函数调用期间不会执行任何其他代码。由于to_string
从不返回空字符串,因此该函数的第二个版本在功能上等效于以下内容:
bool samedigits (int /*number*/){
return true;
// Execution ends with the return statement,so nothing after
// this comment ever executes.
std::cout << "This is dead code. It will never execute.\n";
std::cout << "You will never see this output.\n";
}
要修复第二个版本,您需要在return
条件为true时,在循环中if
仅 。将return true;
移动到循环之后,以便循环可以迭代多次。在检查完所有数字之前,您不希望结束该功能并告诉调用者所有数字都是相同的(return true;
就是这样)。 (如果循环发现不匹配,则执行将到达循环内部的return false;
。这时,函数结束,因此循环后的代码对该函数调用无效。)
一个较小的(美观)解决方案是摆脱break
。假设循环确实进行了足够的迭代以发现不匹配。执行将进入if
语句主体并遇到return false
。此时,在看到break
语句之前,不仅循环停止了,而且整个函数结束了。 break
语句是无效代码,表示永远无法执行的代码。为了到达break
,执行必须经过return
。执行可能会到达一条return
语句,但它不会通过一个。
此外,请务必感谢您的编译器发现此错误,因为它确实指向代码中的错误。这不是编译器报告的确切错误,但是话又说回来,编译器也不是世界上最好的思想家。 :)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。