3

だから私はここ数週間K&Rの本を読んでいます。私はそれをすべて順番に行いましたが、あまりスキップしていません。何かに行き詰まったら、通常は例をグーグルで検索して答えを見つけることができますが、今回は困惑しています。

セクション4.6は、外部と内部の両方で静的変数を宣言することを扱います。演習では、次のように述べています。

演習4-11。ungetchを使用する必要がないようにgetopを変更します。ヒント:内部静的変数を使用してください。

これは、ポーランドの電卓と関係があります。getopは次の演算子またはオペランドを収集し、ungetchは文字を入力スタックにプッシュバックします。

元の関数は次のようになります。

int getop(char s[])
{
int i, c;

while ((s[0] = c = getch()) == ' ' || c == '\t')
    ;

s[1] = '\0';    
if (!isdigit(c) && c != '.' && c != '-' )
    return c;       /* not a number */          
i = 0;
if (c == '-') {
    if (isdigit(c = getchar())) {
        s[i] = '-';
        ungetch(c);
    }
    else {
        ungetch(c);
        return '-';
    }
}

if (isdigit(c))     /* collect integer part */
    while (isdigit(s[++i] = c = getch()))
    ;

if (c == '.')       /* collect a fraction part */
    while (isdigit(s[++i] = c = getch()))
    ;

s[i] = '\0';

if (c != EOF)
    ungetch(c);

return NUMBER;
}

私が調べたほとんどの例は次のようになります。

static int buf = EOF;

if (buf != EOF && buf != ' ' && buf != '\t'
    && !isdigit(buf) && buf != '.') {
    c = buf;
    buf = EOF;
    return c;
}
if (buf == EOF || buf == ' ' || buf == '\t') 
    while ((*s = c = getch()) == ' ' || c == '\t')
        ;
else 
    *s = c = buf;
buf = EOF;

私の問題は、負の数を処理するために、以前にgetopに対して行うことになっていた変更が考慮されていないことです。私が見つけた例はどれも、変数が静的であるという事実を利用していないようであり、したがって、関数が呼び出された後も残ります。最後にEOFに設定しました。関数呼び出しの間に変数が何であるかが問題ではない場合、なぜ静的変数を使用するのですか?

最後に、静的変数を使用してcを入力スタックに戻す方法がわかりません。getchは、getopが認識していないgetchとungetchの間の共有配列を使用します。

このような単純な例の投稿が長くなってすみません。

4

1 に答える 1

2

基本的な考え方は、getop現在持っているungetch()のどこでも、代わりに静的変数を取得できない値に設定することです。次に、 を呼び出すすべての場所でgetch()、有効な場合は代わりに静的変数から値を取得します (有効かどうかを示すために 2 番目の静的変数が必要になる場合があります。これは、読み取り時にクリアし、取得しないときに設定します。それ)。

于 2012-05-03T19:03:12.683 に答える