C函数原型:void f()。是否建议使用?

7
我正在学习C语言。在一本书中看到函数原型的形式是void f(),但在函数声明或调用中,f函数都需要参数。因此,在函数声明中我们会看到类似void f(long double y[], long double A)的形式,而在调用函数时则是f(y, A)。该函数对数组y执行操作,即在调用函数时,数组y中的一些元素会改变。A是一个不变的数值常量。我有两个问题:
  1. 将函数原型定义为void f()是否是一种好的做法?还是像函数声明中那样将它定义为void f(long double y[], long double A)更好?
  2. 被调用的函数f正在更改数组y中的元素。void是否是正确的返回类型?该程序以void作为返回类型描述运行良好。或者我应该将所有的"void"都改为"long double"?我使用长双精度浮点数,因为我需要尽可能高的精度,尽管在我的计算机上double和long double都可以提供15位有效数字。
谢谢!

5
你在哪本书中看到这个的? - anon
“void f(long double y[], long double A)”中,“long double y[]”作为参数是允许的吗? - Andrei Ciobanu
@Andrei:虽然允许这样做,但由于数组在作为参数传递时会被提升为指针类型,因此很少使用。在您的示例中,sizeof(y)将在f()内给出指针大小,而在调用f()的地方(如果数组是静态分配的),它将给出数组大小。 - Anders Abel
@Andres:实际上,数组会衰变成指针。而提升则是发生在整型和浮点型数据类型上的。 - conio
感谢您非常及时的帮助。该书是中村昭一郎的《C语言应用数值方法》(第363页讨论龙格-库塔法)。 - yCalleecharan
在这本书中,使用的是float而不是我在这里提到的long double。我使用long double以获得更好的精度。 - yCalleecharan
3个回答

10

您的问题存在术语混淆。

void f();

在C语言中,不是函数原型。这是一个函数声明,它不会引入原型。同时

void f(long double y[], long double A);

这也是一个函数声明,但这个声明还包含了一个原型(也就是为 f 声明了一个原型)。

回答你的问题,是的,使用函数原型声明函数总是一个好习惯(即与没有原型的情况相比,使用原型声明更好)。通常,你应该为所有外部函数声明原型(而 void f() 不是一个原型)。

至于返回类型,则取决于你的意图。我不认为你改变数组元素的事实应该导致返回 long double 比返回 void 更好。


感谢您指出术语错误,并对函数的“返回”内容进行最后评论。 - yCalleecharan

7
如果在程序开头定义void f()函数原型是个好习惯吗?还是像函数声明那样将它定义为void f(long double y[], long double A)更好?肯定是后者。前者并没有给编译器提供任何类型信息来进行编译时检查。void f()告诉编译器f接受一个未指定参数列表,也就是什么都可以。被调用的函数f正在改变数组y中的元素,void是否是正确的返回类型?即使使用了void,这个程序依然可以正常工作,因为返回类型和修改的参数没有关系。如果你想要表示成功代码,也可以使用非void返回类型。

阅读了您在此处的所有评论后,我了解到尽管void f()可以工作,但并不推荐使用。最好指示编译器正确的参数。 - yCalleecharan

4

声明未指定参数是不好的。在C语言中(但不是在C++中),允许将函数声明为f()而不指定参数,但应避免使用该功能。如果函数不接受任何参数,请使用f(void)显式标记。如果函数接受参数,则始终在声明中包含参数类型。


谢谢澄清。在阅读了这里的三个答案后,我明白代码必须尽可能可读,并且我需要遵循良好的编程标准。 - yCalleecharan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接