在K& R 1.9最长行示例中,getchar()在做什么?

时间:2013-03-28 23:45:39

标签: c kernighan-and-ritchie

我似乎现在理解该程序,除了getline函数不是非常直观,因为它似乎复制了所有getchar()返回到一个永远不会真正用于的字符数组s[]任何重要的事情。

int getline(char s[], int lim)
{
    int c, i;
    for(i=0; i < lim - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
        s[i] = c;
    if(c == '\n')
    {
        s[i] = c;
        ++i;
    }
    s[i] = '\0';
    return i;
}

该函数可以很容易地忽略行s[i] = c;,因为所有函数实际上都在计算字符数,直到它从EOF返回'\n'getchar() }

我真正不明白的是,为什么程序向前推进,因为主循环如下:

main()
{
    int len; /* current line length */
    int max; /* maximum length seen so far */
    char line[MAXLINE]; /* current input line */
    char longest[MAXLINE]; /* longest line saved here */

    max = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        if (len > max)
        {
            max = len;
            copy(longest, line);
        }
    if (max > 0) /* there was a line */
        printf("%s", longest);
    return 0;
}

唯一的解释是getchar()函数在用户输入完整的文本行后发挥其魔力,然后点击 enter 键。所以它似乎在运行期间工作是我的猜测。

这是程序的进展吗?程序是否首先进入while循环,然后等待用户输入一行文本,一旦用户点击进入,getline函数的for循环是否会被迭代?我觉得情况就是这样,因为用户可以在输入过程中输入 backspace

我的问题是,该计划究竟是如何向前发展的?这是因为getchar()功能吗?

当我在终端中点击 ctrl - D 时,会发生其他一些令人困惑的事情。如果我在换行符开始时按 ctrl - D ,程序将终止。如果我在填充了一些文本的行的末尾点击 ctrl - D ,它就不会终止,并且它的行为与点击 enter <的行为不同/ KBD>。如果我在文本行中按 ctrl - D 几次,程序将最终结束。

这只是我的终端处理会话的方式,或者如果我只是想学习C,我不应该担心这一切吗?

我之所以要问的是,我喜欢跟踪程序以便更好地理解它,但是getchar()函数使得这很棘手。

4 个答案:

答案 0 :(得分:3)

getchar从标准输入中读取一个字符。所以,如果那是你坐在终端,它会阻止程序,直到它收到你输入的字符,然后就完成了。但是标准输入在交互时是行缓冲的,因此在您按Enter键之前,程序不会处理您键入的内容。这意味着getchar将能够继续读取您输入的所有字符,因为它们是从缓冲区中读取的。

你错了这个功能。数组传递给函数*,它将每个由getchar读取的字符(EOF或换行符除外)存储在连续的元素中。这就是它的重点 - 不是计算字符数,而是将它们存储在数组中。

(*实际上传递了一个指针,但这里的函数仍然可以像对待数组那样对待它。)

答案 1 :(得分:3)

在参数声明中(在该上下文中仅 ),char s[]实际上意味着char *s。 C标准描述的方式是:

  

参数声明为“ type 的数组”应调整为   “合格的指针   ”。

所以s确实是char*类型的指针,当函数修改s[i]时,它正在修改i的{​​{1}}元素。< / p>

通话中:

line

getline(line, MAXLINE) 是一个数组,但在大多数情况下,数组表达式被隐式转换为指向数组第一个元素的指针。

这两条规则几乎似乎是阴谋的一部分,使它像一样像数组一样,指针在C中实际上是相同的。它们绝对不是。指针对象包含某个对象的地址(或者不指向任何对象的空指针);数组对象包含有序的元素序列。但是大多数C语言中的数组操作是通过指向数组元素的指针完成的,指针算法用于从一个元素前进到下一个元素。

建议阅读(我说了很多):comp.lang.c FAQ的第6部分。

答案 2 :(得分:1)

数组 用于重要的事情:它由调用者提供,并使用新内容返回修改。从合理的角度来看,填充数组是调用函数的目的。

答案 3 :(得分:0)

该数组(数组引用)实际上是一个指针,char s []与char * s相同。所以它在该数组中构建其结果,这就是为什么它稍后在main中复制的原因。在K&amp; R中很少有“魔力”。