C void函数,返回值

时间:2014-07-25 14:25:04

标签: c

至于我知道void函数中的return语句会抛出错误

但是在下面的程序中并非如此

这里输出显示1,怎么来的?

main()
{
    int i=5;
    printf("%d",fun(fun(fun(i))));
}

void fun(int i)
{
    if (i%2)
    {
        return (i+(7*4)-(5/2)+(2*2));
    }
    else
    {
        return (i+(17/5)-(34/15)+(5/2));
    }
}

2 个答案:

答案 0 :(得分:4)

没有表达式的return语句:

void func(void) {
    return;
}

void函数中完全合法。带有表达式的return语句的合法性取决于您正在使用的C语言的版本。

1990 C标准说:

  

带有表达式的 return 语句不得出现在   返回类型为 void 的函数。

该标准的1999年和2011年版本均表示:

  

带有表达式的 return 语句不会出现   在返回类型为 void 的函数中。 return   没有表达式的语句只能出现在函数中   其返回类型为 void

这是约束,这意味着编译器必须为违反它的任何程序发出诊断(可能是非致命警告)。

由于历史原因,C90允许return语句在非void函数中没有表达式。前ANSI C没有void关键字,因此无法定义未返回值的函数。程序员会省略返回类型(默认为int)并忽略它。 C90规则允许这样的旧代码编译而不会出错。您仍然无法从非void函数返回值;如果调用者尝试使用(不存在)结果,则程序的行为是未定义的。 1999年的标准稍微收紧了规则。

您的程序的另一个问题是您在声明可见之前调用fun。根据C99及更高版本的规则,这是非法的(尽管编译器可能只是警告它)。根据C90规则,这是合法的,但编译器将假定函数返回int。您的程序的行为是未定义的,但您的void函数fun可能会像返回一个值一样,并且对它的调用可能会像使用该值一样。

对于某些错误,C编译器往往相当宽松,因此不会拒绝旧代码(有时在第一个实际标准发布之前编写)。但是你的编译器应该至少警告过你return语句,可能还有关于无效调用的警告。你应该密切关注编译器警告;他们的待遇几乎与致命错误一样。您应该使用选项来增加编译器警告您的数量。如果您使用的是gcc,请使用-std=c90-std=c99-std=c11以及-pedantic来强制执行标准一致性。您可以添加-Wall - Wextra`以启用更多警告。

答案 1 :(得分:3)

由于各种原因,您提交的代码实际上在C99中无效,但最痛苦的代码如下:

foo.c:5:17: warning: implicit declaration of function 'fun' is invalid in C99 [-Wimplicit-function-declaration]
    printf("%d",fun(fun(fun(i))));
                ^
foo.c:8:6: error: conflicting types for 'fun'
void fun(int i)
     ^
foo.c:5:17: note: previous implicit declaration is here
    printf("%d",fun(fun(fun(i))));
                ^

请注意,如果您为fun()提供了一个函数原型,那么您应该得到一组不同的错误:

foo.c:7:25: error: passing 'void' to parameter of incompatible type 'int'
    printf("%d",fun(fun(fun(i))));
                        ^~~~~~