3

我现在似乎理解了这个程序,除了这个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. 如果我在一行文本中点击ctrl-D几次,程序最终将结束。

这只是我的终端处理会话的方式,还是如果我只想学习 C 语言,这些都是我不应该担心的?

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

4

4 回答 4

3

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

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

(*实际上传递了一个指针,但是这里的函数仍然可以将其视为一个数组。)

于 2013-03-28T23:57:14.730 回答
3

In a parameter declaration (and only in that context), char s[] really means char *s. The way the C standard describes this is that:

A declaration of a parameter as "array of type" shall be adjusted to "qualified pointer to type".

So s really is a pointer, of type char*, and when the function modifies s[i] it's modifying the ith element of line.

On the call:

getline(line, MAXLINE)

line is an array, but in most contexts an array expression is implicitly converted to a pointer to the array's first element.

这两条规则似乎是为了让数组和指针在 C 语言中看起来真的是一回事。它们绝对不是。指针对象包含某个对象的地址(或不指向任何对象的空指针);数组对象包含有序的元素序列。但是在 C 中对数组的大多数操作都是通过指向数组元素的指针来完成的,指针算法用于从一个元素前进到下一个元素。

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

于 2013-03-29T00:03:59.220 回答
1

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

于 2013-03-28T23:53:48.063 回答
0

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

于 2013-03-28T23:50:26.580 回答