C带返回值的void函数
据我所知,void函数中的C带返回值的void函数,c,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)-
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));
}
}
由于各种原因,您提供的代码实际上在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))));
^~~~~~
不带表达式的
return
语句:
void func(void) {
return;
}
在void
函数中完全合法。带有表达式的return
语句的合法性取决于您使用的C语言版本
1990年的C标准规定:
带有表达式的返回语句不得出现在
返回类型为void的函数
该标准的1999版和2011版均规定:
不应出现带有表达式的返回语句
在返回类型为void的函数中。A返回
没有表达式的语句只能出现在函数中
其返回类型为void
这是一个约束,意味着编译器必须对任何违反它的程序发出诊断(可能是非致命警告)
出于历史原因,C90允许在非void函数中使用不带表达式的return
语句。前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`以启用更多警告。在原型出现之前使用fun
可能会产生混乱的后果。这意味着它返回int
,谁知道在以后定义它时编译器是如何解析的呢?从C99开始,这将被禁止。事实上,此代码段产生的编译器警告行数与相关代码行数相当。从来都不是好兆头,这是未定义的行为。我在没有编译器优化的情况下得到1,在编译器优化的情况下得到0。我不知道它是好是坏,但有时我在void返回函数中使用了很多“空”返回。@jewelstepher:这是非常有效的。虽然作为一个好的设计,有些人提倡写作功能,所以他们只从一个角度出发;早期的return
s(带或不带值)会使控制流更难分析。