我似乎现在理解该程序,除了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()
函数使得这很棘手。
答案 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中很少有“魔力”。