来自《Understanding Unix Programming》,第 1.6 章,more01.c
示例:
int see_more(), reply;
我尝试了一些类似的代码:
#include <stdio.h>
int main()
{
int hey(), reply;
return 0;
}
int hey()
{
printf("Hello");
};
日志中没有错误,但Hello
控制台上没有。有人可以解释一下吗?
这将编译得很好。但你所做的只是声明函数。这与在顶层添加(非原型)声明相同。
int hey( );
// ^ empty parens means it's not a prototype
如果它是初始化程序的一部分,您可以在声明中调用函数。
#include <stdio.h>
int main()
{
int reply=hey();
// ^ here the function is called, even though this is a declaration,
// because the value is needed.
return 0;
}
int hey(){
return printf("Hello");
// a function returning `int` ought to `return ` an int!
};
但通常要调用函数,您只需将调用放在(非声明)表达式语句中。
#include <stdio.h>
int main()
{
int reply; // declaring a variable
int hey(); // declaring a function
(void) hey(); // function call, casting return value to (void)
return 0;
}
int hey(){
return printf("Hello");
};
在一些早期的编译器中有一个限制,即只有最后一个声明可以包含函数调用。C99(和大多数“现代”编译器)已经放宽了这个限制,现在可以在初始化程序中使用函数调用而不受惩罚。
IIRCsplint
语法检查器对初始化程序中的函数调用具有相同的限制。
它可能被认为是不好的风格,但在没有原型的情况下调用函数并不一定是不正确的。可以肯定的是,它消除了编译器从类型角度检查调用是否有意义的能力。但你真正要做的就是不要搞砸了。
非原型函数将默认为标准调用约定,这意味着所有整数 args (char, short, int) 提升为int
并且所有浮点 args 提升为double
。这些提升也适用于使用#include <stdarg.h>
(以及我们心爱的printf
)的可变参数函数,因此我认为了解如何调用非原型函数非常有用。
我在这里有一些“不要搞砸”的代码,它通过函数指针调用非原型函数。这一切都有效并符合标准(接近我可以想象的),但我不知道如何对可能指向许多刻板模式之一的函数指针进行原型设计。使用 variadic notation 是不正确的(...)
,因为它不是一回事。只是没有合适的方法来原型化它,所以指针只是声明为void (*fp)();
.
你只是在那里声明函数,而不是调用它。
像这样:
int main()
{
extern int hey(); // there is a function "hey" somewhere
hey();
}
int hey()
方法不返回任何值。尝试制作它void hey()
。