例如:
int f1() {
return 3;
}
void f2(int *num) {
*num = 3;
}
int n1, n2;
n1 = f1();
f2(&n2);
使用f1,我们可以返回一个值并执行" variable = f1()" 但是同样可以使用void函数来完成,该函数在给定地址的情况下更新该变量的值,而不必执行" variable = f1()"。
那么,这是否意味着我们实际上只能将void函数用于一切?或者是否有一些void函数无法替换另一个int函数/(类型)函数?
答案 0 :(得分:7)
将所有内容都设置为无效功能(在某些人的词典中被称为"例程")的主要问题是您无法轻松链接它们:
f(g(x))
成为,如果你真的想链接它:
int gout;
f((g(x, &gout), gout))
这很痛苦。
答案 1 :(得分:3)
是的,您可以为所有内容使用void
返回类型,并完全依赖于通过修改后的参数返回。实际上,您可以完全避免使用函数并将所有内容放在main
方法中。
与该语言的任何其他功能一样,返回值会为您提供特别的优势,由您决定是否需要它们。以下是返回值的一些优点:
const
变量,这可以使您的代码更容易推理使用返回值的代码通常更容易阅读,尤其是当函数是数学函数时(例如,如果需要输出,想象必须使用sin / cos /等手动声明所有临时对象进行大数学运算)通过参数)。比较:
double x = A*sin(a) + B*cos(b);
与
double tmpA, tmpB;
sin(&tmpA, a);
cos(&tmpB, b);
double x = A * tmpA + B * tmpB;
或使用John Zwinck在答案中建议的类似结构:
double tmpA, tmpB;
double x = A * (sin(&tmpA, a), tmpA) + B * (cos(&tmpB, b), tmpB);
无论函数内部发生什么,都可以保证设置该值,因为这是由编译器强制执行的(除了一些非常特殊的情况,例如longjumps)
当然也有缺点:
答案 2 :(得分:2)
那么,这是否意味着我们实际上只能将void函数用于一切?
事实上。事实证明,这样做是一种相当常见的编码风格。但是这些样式通常表明应该始终为错误代码保留返回值,而不是void
。
在实践中,你通常无法始终如一地坚持这种风格。有一些特殊情况,不使用返回值变得不方便。
例如,在编写标准C泛型函数bsearch
或qsort
使用的回调函数时。期待回调格式
int compare (const void *p1, const void *p2);
其中函数返回小于零,大于零或零。在设计方面,保持参数以只读方式传递非常重要,您不希望通用搜索算法突然开始修改搜索到的内容。因此,虽然理论上没有理由为什么这些函数也不能成为void
返回类型,但在实践中它会使代码更难以阅读。
答案 3 :(得分:1)
当然可以;但这并不是一个好主意。
它可能并不总是方便或导致易于理解的代码。返回void的函数不能直接用作表达式中的操作数。例如,你可以写:
if( f1() == 3 )
{
...
}
f2()
你必须写:
f2( &answer ) ;
if( answer )
{
...
}
另一个问题是访问控制之一 - 通过将指针传递给您正在为该函数提供间接访问调用者数据的函数,只要函数表现良好且不会溢出,这就很好。指针可以引用单个对象或对象数组 - 该指针必须执行适当规则的函数,因此本质上不太安全。