微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

什么时候从函数返回?

如何解决什么时候从函数返回?

如果问题听起来很幼稚,请提前抱歉。我正在编写一个简单的布尔函数,以检查数字的所有数字是否相同。以下作品,但是之后的作品,给我一个错误

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 < 3snumber的大小为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 举报,一经查实,本站将立刻删除。