12

誰でも unetch の目的を説明できますか? これは、逆ポーランド電卓を作成する K&R の第 4 章からのものです。

ungetch を呼び出さずにプログラムを実行しましたが、テストでも同じように動作します。

 int getch(void) /* get a (possibly pushed back) character */
    {
        if (bufp > 0)
        {
            return buf[--bufp];
        }
        else
        {
            return getchar();
        }
    }

    void ungetch(int c) /* push character back on input */
    {
        if (bufp >= BUFSIZE)
        {
            printf("ungetch: too many characters\n");
        }
        else
        {
            buf[bufp++] = c;
        }

}

(わかりやすくするために、getch の三項演算子を削除しました。)

4

4 に答える 4

32

あなたが言及している具体的な例については知りませんが (K&R を読んでからおそらく 23 年経っていますが、それが初版でした)、多くの場合、解析するときに次の文字を「のぞいて」確認するのが便利です。それはあなたが現在解析しているものの一部です。たとえば、数字を読んでいる場合、数字がなくなるまで数字を読み続けたいとします。Ungetc を使用すると、数値リーダーは次の文字を消費せずに見ることができるため、他の人が読み取ることができます。Greg Hewgill の「2 3+」の例では、数値リーダーは 3 桁を読み取り、次にプラス記号を読み取って数字が終了したことを認識し、後で読み取れるようにプラス記号を取り出します。

于 2009-01-24T20:37:51.553 に答える
10

演算子の前後にスペースを入れずにプログラムを実行してみてください。その例の形式を正確に思い出せませんし、K&R も手元にありませんが、"2 3 +" を使用する代わりに "2 3+" を試してください。数値パーサーは、数字以外のungetch()ものを取得するまで数字を読み取るため、おそらく数字を解析するときに使用されます。数字以外がスペースの場合、次getch()は を読み取り、+すべて問題ありません。ただし、次の非数字が である場合は+、それを入力ストリームにプッシュして戻す必要があります。これにより、メインの読み取りループが再びそれを見つけることができます。

例を正しく覚えていることを願っています。

于 2009-01-24T20:33:22.357 に答える
4

これは、字句スキャナー (テキストを変数名、定数、演算子などのチャンクに分割するコンパイラーの一部) によく使用されます。この機能はスキャナには必要ありません。非常に便利です。

たとえば、変数名を読んでいるとき、変数名の一部ではない文字を読むまで、いつ終わったかわかりません。ただし、その文字を覚えて、それをレクサーの次のチャンクに伝える方法を見つける必要があります。グローバル変数か何かを作成したり、それを呼び出し元に渡したりすることはできますが、エラー コードなどの他のものを返すにはどうすればよいでしょうか。代わりに、文字を ungetch() して入力ストリームに戻し、変数名で必要なことをすべて実行して戻ります。次に、レクサーが次のチャンクの読み取りを開始するときに、余分な文字が転がっているのを探し回る必要はありません。

于 2009-01-24T20:43:43.333 に答える
-3

このコードを見てください、あなたは理解するでしょう:

#include <conio.h>
#include <stdio.h>
int main()
{
    int y=0;
    char t[10];
    int u=0;
    ungetch('a');
    t[y++]=getch();
    ungetch('m');
    t[y++]=getch();
    ungetch('a');
    t[y++]=getch();
    ungetch('z');
    t[y++]=getch();
    ungetch('z');
    t[y++]=getch();
    ungetch('a');
    t[y++]=getch();
    ungetch('l');
    t[y++]=getch();
    ungetch('\0');
    t[y++]=getch();
    ungetch('\0');
    t[y++]=getch();
    ungetch('\0');
    t[y++]=getch();
    printf("%s",t);
    return 0;
}
于 2012-07-16T15:34:33.603 に答える