我在DOOM源代码中发现了以下模式,但不确定该怎么做。
The declaration and use .c file
@IBAction func removeButton(_ sender: Any) {
labels.forEach { $0.removeFromSuperview() }
labels.removeAll()
}
enemy.c
// A nice definition, but there is no corresponding header file, kind of weird
void A_Pain (mobj_t* actor)
{
if (actor->info->painsound)
S_StartSound (actor, actor->info->painsound);
}
info.c
当其余代码库使用头文件时,为什么不使用头文件?这种方法有优势吗?
为什么要在具有不同签名的不同源文件中声明函数?
答案 0 :(得分:3)
我认为这不是好习惯。但是根据我对C标准的理解,当您声明类似void A_Pain();
之类的函数时,该函数可以采用任意数量的参数,这与C ++不同。因此,在C语言中,您需要使用void A_Pain(void);
来表示它没有参数。
但是在C ++中,void A_Pain();
表示它不接受任何参数。
答案 1 :(得分:0)
在C中,声明T f()
没有声明函数f
返回T
并接受零参数;它声明函数f
返回T
并接受未指定数量的参数。
即使函数定义位于源文件不知道的转换单元中,您也可以将函数声明放在源文件中,因为将它们全部连接在一起是由链接器而不是编译器完成的。
答案 2 :(得分:0)
为什么不使用头文件?
这并没有真正的区别,头文件仍然只是文本包含。将声明放入头文件中很有道理,尤其是在多个地方使用了声明的情况下,但不是必需。只要每个编译单元都同意名称的含义,一切都会正常进行。
为什么要在具有不同签名的不同源文件中声明函数?
它们没有不同签名;如果他们这样做了,那就有问题了。但是info.c
中的声明具有 no 参数列表。只要“参数列表 [在定义中] 不应带有省略号终止符,并且每个参数的类型应与默认参数提升产生的类型兼容”,则允许这样做(N1256 6.7.5.3,这可能是适用于Doom的规范的错误版本,但这并不重要)。换句话说,如果一个函数没有签名就被声明,则其参数的数量和类型将根据其调用方式来推断。只要此推断是正确,您就有一个可以正常运行的有效程序。它只是老式的,由于缺乏显式性,因此难以维护。