我正在阅读"编译器设计在C"书。在基础部分,我找到了一个类似于lexer的c片段 -
static int Lookahead = -1;
int match(token)
int token;
{
if(Lookahead == -1)
Lookahead = lex();
return token == Lookahead;
}
void advance(){
Lookahead = lex();
}
我对如何在gnu gcc上编译匹配函数感到困惑。所以我写了一个看起来像
的函数int a(token)
int token;
{
printf("Value of token is %d", token);
}
int main()
{
printf("Hello world!\n");
a(1);
return 0;
}
我得到了以下输出 -
你好世界! 令牌的值是1
但我没有得到这个功能声明背后的原因。以这种方式声明功能有什么好处?而令牌的价值如何为1?为什么它不是编译错误?它是C中的某种函数声明吗?
感谢您查看我的问题。任何形式的帮助都会很棒。
答案 0 :(得分:6)
它是一种旧的,已弃用的K& R风格的功能声明。
int match(token)
int token;
{
// Function body
}
相当于
int match(int token)
{
// Function body
}
除了在前者中,编译器不会检查函数是否使用正确数量的参数调用,也不会检查参数的类型。它依赖于默认参数促销 C89和C99也支持这种风格。
答案 1 :(得分:4)
当Kernighan和Ritchie首次开发C编程语言时,这是C函数的原始方式。它被称为'K& R C'
C经历了一个标准化过程,这种形式的功能声明被改为你习惯的那种。
在页面http://en.wikipedia.org/wiki/The_C_Programming_Language上,本书的第一版将具有旧样式函数声明,我认为它已在第二版中删除。
答案 2 :(得分:2)
原始K& R C中的功能定义更简单。在您的示例中,函数参数令牌的类型声明实际上是多余的。代码可以通过这种方式简化:
static int Lookahead = -1;
int match(token) {
if (Lookahead == -1)
Lookahead = lex();
return token == Lookahead;
}
void advance(){
Lookahead = lex();
}
实际上函数返回类型和变量类型也默认为int,void尚未发明,return语句是可选的......导致进一步简化:
static Lookahead=-1;
match(token){
if(Lookahead==-1) Lookahead=lex();
return token==Lookahead;
}
advance(){Lookahead=lex();}
这种原始样式更紧凑,但非常容易出错,并且不再受现代合规编译器的支持。您的示例中的函数定义语法仍然受支持,但在某些时候被认为是过时的并且可能会消失。