C 为什么我的函数总是出错?

C 为什么我的函数总是出错?,c,cs50,collatz,C,Cs50,Collatz,如果我将函数更改为void,则会收到错误消息 #include <stdio.h> #include <cs50.h> int collatz(int n); int main(void) { int x = get_int("number: "); collatz(x); printf("%d", collatz(x)); } int collatz(int n) { if (n == 1)

如果我将函数更改为void,则会收到错误消息

#include <stdio.h>
#include <cs50.h>

int collatz(int n);
int main(void)
{
    int x = get_int("number: ");
    collatz(x);
    printf("%d", collatz(x));
}

int collatz(int n)
{
    if (n == 1)
        return 0;
    else if ((n % 2) == 0)
        return 1 + collatz(n/2);
    else if ((n % 2) == 1)
        return 1 + collatz((n*3) + 1);
}
collatz.c:20:1: error: control may reach end of non-void function
      [-Werror,-Wreturn-type]
}
error: control may reach end of non-void function

我是不是做错了什么?collatz函数返回一个值,但函数在void和int下都不能正确编译。

只需添加一个额外的分支,即可使编译器满意:

collatz.c:15:9: error: void function 'collatz' should not return a value
      [-Wreturn-type]
        return 0;

重写
collatz
,以便编译器可以看到它不能在不点击
return
语句的情况下退出:

int collatz(int n)
{
if (n == 1)
    return 0;
else if ((n % 2) == 0)
    return 1 + collatz(n/2);
else if ((n % 2) == 1)
    return 1 + collatz((n*3) + 1);
else
    return -1; // this happen if called with odd negative n.
}

警告消息清楚地解释了编译器抛出它的原因

int collatz(int n)
{
    if (n == 1)
        return 0;

    if ((n % 2) == 0)
        return 1 + collatz(n/2);

    return 1 + collatz((n*3) + 1);
}
这意味着不能保证函数将返回某些内容。函数的返回类型是
int
,因此它需要返回
int
。您的
if-else
条件并非详尽无遗(考虑负数),因此控制流可能到达函数末尾而不返回任何内容

如果我将函数更改为void,则会收到错误消息

#include <stdio.h>
#include <cs50.h>

int collatz(int n);
int main(void)
{
    int x = get_int("number: ");
    collatz(x);
    printf("%d", collatz(x));
}

int collatz(int n)
{
    if (n == 1)
        return 0;
    else if ((n % 2) == 0)
        return 1 + collatz(n/2);
    else if ((n % 2) == 1)
        return 1 + collatz((n*3) + 1);
}
collatz.c:20:1: error: control may reach end of non-void function
      [-Werror,-Wreturn-type]
}
error: control may reach end of non-void function
如果将函数返回类型更改为void,则无法从中返回int。因此,这是一条信息

正如其他人已经建议的那样,您需要以这样一种方式重写函数,即编译器能够确定是否会命中某些
return
语句


另外,WeatherVane指出了代码中一些更严重的错误。请注意它们。

一个
int
输入在其值最终变成
1
之前能变成多大?想想当你输入一个大的奇数时会发生什么。你已经调用了两次
collatz
,并放弃了第一个结果。你还可以忽略最后一个
或者
。但是,它可能会提高可读性。如果在函数开始之前或甚至在调用之前剔除负值,那么代码> %n 2 只能执行一次,因为只有两个可能的值,并且<代码> E/<代码> s仅是函数返回以来的混乱。