3

「Compiler Design in C」という本を読んでいました。基本セクションで、このようなレクサーのacスニペットを見つけました-

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の関数宣言のようなものですか?

私の質問をチェックしてくれてありがとう。どんな種類の助けも素晴らしいでしょう。

4

3 に答える 3

6

古い非推奨の K&R スタイルの関数宣言です。

int match(token)
int token;
{
    // Function body
}  

と同等です

int match(int token)
{
    // Function body
}    

ただし、前者では、コンパイラは、関数が正しい数の引数で呼び出されていることを確認したり、引数の型を確認したりしません。デフォルトの引数の昇格に依存しています。
C89 と C99 もこのスタイルをサポートしています。

于 2015-02-22T08:02:02.323 に答える
4

これは、カーニハンとリッチーが最初に C プログラミング言語を開発したときに C 関数が宣言されていた元の方法です。「K&R C」と呼ばれています。

C は標準化プロセスを経て、この形式の関数宣言が慣れ親しんだ形式に変更されました。

http://en.wikipedia.org/wiki/The_C_Programming_Languageのページでは、本の初版には古いスタイルの関数宣言が含まれていたはずですが、2 版では削除されたと思います。

于 2015-02-22T08:03:36.723 に答える
2

元の K&R C の関数定義はより単純でした。あなたの例では、関数パラメーター token の型宣言は実際には冗長です。コードは次のように簡略化できます。

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();}

このようなプリミティブ スタイルはよりコンパクトでしたが、エラーが発生しやすく、最新の適合コンパイラではサポートされていません。あなたの例の関数定義構文はまだサポートされていますが、時代遅れであると考えられており、ある時点で消える可能性があります。

于 2015-02-22T09:12:21.980 に答える