我不明白为什么我们需要在函数结尾使用return 0;
。我不知道为什么我们需要它在main()
的末尾(为了表示程序结束?),但我真的不明白为什么我们在普通函数结束时还需要它。为什么我们需要在C函数的末尾使用'return 0'?
回答
如果您将返回类型声明为void
您不需要在每个函数中都返回0。例如:
void my_function(int *p_data)
{
*p_data = 5;
}
int main(void)
{
int data = 0;
my_function(&data);
printf("Data: %d", data);
return 0;
}
这将工作得很好。
如果在你的代码,你说你的函数返回一个值,但你实际上并没有返回一个:
int my_function(int x)
{
// bad practice!
}
...这是错误不好的做法。你说你要返回一个值(在这个例子中是'int'),但你没有。
同样,如果有通过你的功能的多条路径:
int my_function(int x)
{
if (x == 3)
return 42; // good
// bad!
}
你又把声明的意图返回一个值,而是通过你的函数一些路径不这样做,那也是错误不好;你已经违背了你对函数调用者的承诺。
通过函数的所有路径应在return语句结束:
int my_function(int x)
{
if (x == 3)
return 42; // good
return 1; // good
}
如果你不想返回任何值,然后声明函数void:
void my_function(int x)
{
// good
}
UPDATE :以上,您可能会注意到我将“错误”替换为“不良做法”。这是因为“错误”这个词在C标准中非常特别,并且忘记return
声明不符合该定义(相反,它被认为是“未定义的行为”,并且您的编译器甚至可能不会抱怨)。但是,你作为一个人应该认为它是你的代码中的一个错误,并且避免在函数外的所有退出路径上遗忘返回语句。
C中省略return语句并不是错误。如果你既省略了return语句,又试图在调用代码中使用返回值,那只是一个错误。 (而这种错误的本质是未定义的行为,不需要诊断 - 编译器不必警告这一点,尽管一些人会这样做)。 –
虽然你的评论是正确的,但看起来OP是一个新手,我觉得这样的细节对于他/她来说太早了。我的回答是前瞻性的,朝着良好的编程习惯。如果你喜欢,我可以把我的话'错误'改为'坏' –
如果一个函数声明为返回void
以外的类型,那么它必须有有一个return语句。唯一的例外是main
函数,该函数从C99开始可以省略return
语句(省略时,行为与在main
的关闭}
之前有return 0;
语句相同)。
考虑这个错误test
功能:如果你调用test
以0作为参数
int test(int a)
{
if (a == 0)
return 123;
}
int main()
{
int x;
x = test(0); // x equals 123
x = test(1); // x equals ???
}
,功能会给你回123,但是如果你比0以外的称呼呢?你期望的结果是什么?对于C中的函数,没有“默认返回值”,如果返回类型不是void
(有一个例外是main
函数),则返回值必须。
- 1. 我们必须在函数“return”的末尾写什么?在C++
- 2. 什么是仿函数,为什么我们需要它们?
- 3. 为什么我们应该在button_press_event.handler的末尾返回True?
- 4. 装配需要什么?为什么我们使用它们?
- 5. 为什么我们需要在JavaScript
- 6. 何时/为什么'\ 0'需要标记(char)数组的结尾?
- 7. 为什么你需要一个URL末尾的斜线?
- 8. 为什么在c中定义常量的末尾使用'e0'?
- 9. 为什么我们需要装饰器中的包装函数?
- 10. 为什么我们需要OOP中的构造函数?
- 11. 为什么我们在使用return时使用pthread_exit()?
- 12. 为什么C++字符串需要\ 0?
- 13. 为什么我们需要在Elixir中使用“捕获操作符”函数?
- 14. 为什么我们只需要为Scalar函数使用Schema名称
- 15. 为什么我需要libprofiler.so.0
- 16. 为什么我们需要.htaccess的worpdress?
- 17. 为什么我们需要一个构造函数?
- 18. 为什么我们需要一个私人构造函数?
- 19. 我们为什么需要纤维
- 20. 为什么我需要在sigaddset()之前使用sigemptyset()函数?
- 21. 为什么我们需要在C++中使用extern“C”{#include <foo.h>}?
- 22. C#代表,为什么我们需要它们?
- 23. 为什么我们必须在react-native的promise链末尾调用`.done()`?
- 24. 为什么我们需要在C#属性
- 25. 我们是否需要显式调用“return”在构造函数中?如果是,那么为什么,我需要一个完整的理由背后
- 26. 为什么我们需要在调用函数时递减堆栈指针
- 27. 为什么在调用我的javascript函数时需要'javascript:'?
- 28. 为什么我们需要fieldset标签?
- 29. 为什么我们需要RIA?
- 30. 为什么我们需要9补丁?
它取决于 - 它只是表示没有错误的惯例 –
如果你想让调用进程知道它执行的程序的状态,你需要在'main'的末尾返回一个值。例如,Windows批处理文件可以根据程序返回的值使用'errorlevel'来采取行动。 –
'main'是*不需要'return'语句(从C99开始)的唯一函数。 – dreamlax