3

所以过去几周我一直在阅读 K&R 的书。我已经按顺序完成了所有操作,并没有真正跳过太多。如果我遇到问题,我通常可以用谷歌搜索示例并找到答案,但这一次,我被难住了。

4.6 节涉及在外部和内部声明静态变量。练习是这样说的:

练习 4-11。修改 getop 使其不需要使用 ungetch。提示:使用内部静态变量。

这与波兰计算器有关。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 使用 gettop 不知道的 getch 和 ungetch 之间的共享数组。

抱歉,对于这样一个简单的示例,帖子较长。

4

1 回答 1

2

基本思想是,在getop您当前拥有的任何地方,您都ungetch()可以将静态变量设置为您无法获得的值。然后,在您调用的任何地方getch(),您都会从静态变量中获取值,而不是如果它有效(您可能需要第二个静态变量来说明它是否有效,您在阅读时清除它,并在您取消进入时设置它)。

于 2012-05-03T19:03:12.683 回答