我并不是在为这个练习而挣扎(天哪,在1-20到1-24之后……),但我想知道我的解决方案是否出了问题。该练习要求您编写一个相当于以下内容的循环:
for (i=0; i<lim-1 && (c=getchar()) != '\n' && c!= EOF; ++i)
s[i] = c;而不使用\或&&。我选择不使用任何尚未向我介绍的语言特性,我认真地认为,每个练习都放在它的位置,因为它的意图是用户使用所提供的概念。因此,我想出了这个问题:
for (i=0; (i<lim-1) == ((c=getchar()) != EOF) == (c != '\n'); ++i)
s[i] = c;有一个更漂亮的解决方案,其中包含一个简单的if/else if类型条件,但我想利用本节中关于基于真值或假值的表达式的讨论。问题是,我的解决方案并没有出现在我通常检查的有效锻炼解决方案的任何网站上,所以即使它看起来同样有效。我在想,除了丑陋之外,我的做法是否有什么问题?功能在某种程度上有差异吗?
发布于 2014-10-30 05:35:37
除了其他任何东西,它是未定义的行为,因为它取决于评估顺序。&&和||肯定会先计算它们的左操作数,但==不会。因此,不能保证第二次使用c时会引用新值,而不是前一个循环中的值(或者第一次使用统一值)。
&&的短路计算是原回路语义的重要组成部分.如果第一个操作数为false,则&&不计算其第二个操作数,这意味着保证原始循环调用getchar的次数不超过lim-1次数。在没有&&的情况下重写后,getchar将被称为i到达lim-1的额外时间,并且字符读取(如果有)将被丢弃到位桶中,这意味着在下一次尝试读取输入时它将丢失。
最后,a == b与a && b不一样。它适用于(c != EOF) == (c != '\n'),因为不可能这两种情况都是假的--这是一个有趣的观察--但它并不是(i < lim-1) && ...的替代品。
发布于 2014-10-30 10:15:44
// with the use of break statement and no else statements
for( i=0; i<(lim-1); ++i )
{
c = getchar();
if( '\n' == c ) break;
if( EOF == c ) break;
s[i] = c;
}发布于 2014-10-30 05:35:52
您的代码可能有未定义的行为。在GCC和Clang的指导下,我也提出了类似的警告:
test.cpp:14:31: warning: unsequenced modification and access to 'c'
[-Wunsequenced]
for (i=0; (i<lim-1) == ((c=getchar()) != EOF) == (c != '\n'); ++i)阅读C中的序列点和C-常见问题3.8我不相信==是序列点,但&&是。第二,我不认为你的代码能像你想的那样。如果我们以下面的例子为例:
#include <stdio.h>
int main()
{
int lim = 512;
int a = 1;
char b = EOF;
char c = '\n';
if ((a < lim) == (b != EOF) == (c != '\n'))
{
printf("True.");
} else {
printf("False.");
}
}它输出“真”。因此,这实际上是错误的。我建议您尽量避免编写聪明的代码,而应该坚持您提到的"if/else“解决方案。
while(i < lim-1) {
c = getchar();
if (c == '\n')
lim = 0; /* We haven't encountered breaks yet. */
else if (c == EOF)
lim = 0;
else
s[i++] = c;
}https://stackoverflow.com/questions/26645484
复制相似问题