在Brian & Dennis编写的关于C语言“C编程语言”的经典著作“C编程语言”( the C Programming language )的第1.9章中,有一堆关于函数'getline‘的代码,用于将下一行输入文本复制到char类型字符串并检查溢出。我引用以下代码:
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;
}问题是:参数‘极限’是行的最大长度,因此数组s[]只能包含从s到sLim-1的元素集合。如果变量c到getchar()的最后一个字符是'\n‘,并且这个字符的索引是极限-1,那么' for’循环中的判断部分将失败,因为‘i==极限-1’,而不是'c!='\n‘(根据从左到右的顺序)。接下来,如果子句可以工作,因为‘c=’\n‘,那么sLim-1=c,那么++i将i的值设置为limit。si='\0‘将溢出,因为slimit超出了字符串的限制。我的分析对不对?谢谢你有任何有用的答案。
发布于 2014-08-08 18:07:05
你的分析错了。如果是i == limit-1,由于短路评估,环路中断而不读入c .所以,你永远不会进入if (c == '\n')。i保持为limit-1,并且没有溢出。
在概念上,您可以这样想循环条件:“如果i低于limit-1,读取一个字符,如果不是EOF或换行符,则输入循环体。”因此,如果i是limit-1,则永远不会阅读。
发布于 2014-08-08 18:17:38
在这段代码中有两个短路的等值点.见下文
for (i=0; i<limit-1 && (c=getchar())!=EOF && c!='\n'; ++i)
// ( A ) ( B ) ( C )所有这些都用一条&&链分开。当执行此代码时,这三种情况都必须为真,否则循环将中断。但在短路的情况下,会发生以下情况:
所以..。
i<limit-1是假的,则既不执行getchar()和对EOF的比较,也不执行与'\n'的比较。(c=getchar())!=EOF为false,则不执行与'\n'的比较。'\n'的比较。我希望这是有意义的。
https://stackoverflow.com/questions/25209442
复制相似问题