[英]Is there an error in the example code in chapter 1.9 in the classic book “The C Programming Language”?
In the Chapter 1.9 in the classic book about C language "The C Programming Language" by Brian & Dennis, there is a bunk of code about a function 'getline' which is used to copy the next line of input text into a char type string and check the overflow. 在Brian&Dennis关于C语言“The C Programming Language”的经典着作的第1.9章中,有一个关于函数'getline'的代码,用于将下一行输入文本复制到char类型字符串中并检查溢出。 I quote the code below: 我引用下面的代码:
int getline(char line[], int maxline);
int getline(char s[], int limit)
{
int c,i;
for (i=0; i<limit-1 && (c=getchar())!=EOF && c!='\n'; ++i) /* ** */
s[i]=c;
if (c == '\n') {
s[i]=c;
++i;
}
s[i] = '\0';
return i;
}
Here is the problem: the parameter 'limit' is the max length of the line, so the array s[] can only contain a collection of elements from s[0] to s[limit-1]. 这是问题:参数'limit'是行的最大长度,因此数组s []只能包含从s [0]到s [limit-1]的元素集合。 If the last character for the variable c to getchar() is '\\n' and this character's index is limit-1, then the judgement part in the 'for' loop will fail because of 'i==limit-1' but not 'c!='\\n' (according to the sequence from left to right). 如果变量c到getchar()的最后一个字符是'\\ n'并且此字符的索引是limit-1,那么'for'循环中的判断部分将因'i == limit-1'而失败但不会'c!='\\ n'(根据从左到右的顺序)。 Next, if clause will work, because of 'c=='\\n'', then s[limit-1]=c, then ++i will set the value of i into limit. 接下来,if子句将起作用,因为'c =='\\ n'',然后s [limit-1] = c,那么++ i将i的值设置为limit。 s[i]='\\0' will overflow, because s[limit] overrun the limit of string. s [i] ='\\ 0'将溢出,因为s [limit]超出了字符串的限制。 Is my analysis right or not? 我的分析是否合适? Thanks for any helpful answers. 谢谢你的任何有用的答案。
Your analysis is wrong. 你的分析是错误的。 If i == limit-1
, the loop breaks without reading into c
, due to short-circuit evaluation. 如果i == limit-1
,由于短路评估,循环中断而不读入c
。 So, you never enter if (c == '\\n')
. 所以,你永远不要输入if (c == '\\n')
。 i
remains limit-1
and there is no overflow. i
仍然是limit-1
并且没有溢出。
Conceptually, you can think of the loop condition like this: "If i
is lower than limit-1
, read a character, and if it's not EOF or newline, enter the loop body." 从概念上讲,你可以想到这样的循环条件:“如果i
低于limit-1
,则读取一个字符,如果它不是EOF或换行符,则进入循环体。” Thus, if i
is limit-1
, you never read. 因此,如果i
是limit-1
,你永远不会读。
There are two short circuited eval-points points in this code. 此代码中有两个短路的eval-points点。 See below 见下文
for (i=0; i<limit-1 && (c=getchar())!=EOF && c!='\n'; ++i)
// ( A ) ( B ) ( C )
All are separated with a chain of &&
. 所有都用&&
链分开。 When this code executes, all three must be true or the loop will break. 执行此代码时,所有三个必须为true或循环将中断。 But with short circuit eval the following happens: 但随着短路评估,会发生以下情况:
Therefore... 因此...
i<limit-1
is false, neither the getchar()
and comparison against EOF, nor the comparison against '\\n'
are performed. 如果i<limit-1
为false, 则不执行getchar()
和与EOF的比较,也不执行与'\\n'
的比较。 (c=getchar())!=EOF
is false, then the comparison against '\\n'
is not performed. else if (c=getchar())!=EOF
为false,则不执行与'\\n'
的比较。 '\\n'
is performed. 否则执行与'\\n'
的比较。 i hope that made sense. 我希望这是有道理的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.