我正在通过K&R (第二版)进行自我启迪,并遇到了以下练习(练习2-2 p42):
Write a loop equivalent to the following without using && or ||:
for (i=0; i<lim-1 && (c=getchar()) != '\n' && c != EOF; ++i)
s[i] = c;这是我的解决方案:
#include <stdio.h>
/* write a loop equivalent to the following without using && or ||
for (i=0; i<lim-1 && (c=getchar()) != '\n' && c != EOF; ++i)
s[i] = c;
*/
int main()
{
int counter = 0, lim = 1000;
int s[lim], c;
while(counter < lim-1)
{
while((c = getchar()) != '\n')
{
while(c != EOF)
{
s[counter] = c;
}
}
counter++;
}
return 0;
}我以为一旦遇到换行符('\n')或EOF字符(在我的Linux机器上是Ctrl-d),缩进的循环就会正常退出,但令我惊讶的是,它很高兴地继续运行。我试着用gdb调试它,但还是搞不清楚。
我没看到的是什么?
附录:我试图颠倒while循环执行的测试顺序,并添加了一条if语句来中断外部循环if c == '\n',但我仍然看不到它!我也很难运行GDB在命令行中输入文本并同时打印c的值,即使我试图将gdb链接到可执行文件的运行副本的pid。我意识到可能还有其他方法来解决这个练习,例如,只有在所有三个条件都满足的情况下,才能设置OK_TO_EXECUTE标志或变量为真,但令我困扰的是,我似乎无法在一个看似简单的程序中找到错误。这就是为什么我要回到K&R来更彻底地阅读这本书,并适当地解决练习。
重做代码(仍有错误!):
#include <stdio.h>
/* write a loop equivalent to the following without using && or ||
for (i=0; i<lim-1 && (c=getchar()) != '\n' && c != EOF; ++i)
s[i] = c;
*/
int main()
{
int counter = 0, lim = 1000;
int s[lim], c;
while((c = getchar()) != EOF)
{
if ( c == '\n')
break;
while(c != '\n')
{
while(counter < lim-1)
{
s[counter] = c;
counter++;
}
}
}
return 0;
}解决了,-我想是的我想我终于想通了。在我的重做解决方案中编写的内部循环仍然会无休止地循环,或者至少会循环到lim。我添加了break语句,并认为我正在寻找解决方案。
不过,我仍然在苦苦思索如何在这个问题上运行gdb;输入命令行条目并对c的值执行print操作。将gdb链接到可执行文件的pid仍然无法按预期工作。我甚至发布了一个关于gdb的separate question。
发布于 2013-04-08 03:03:27
您添加了原始版本中不存在的循环...这在概念上和逻辑上都是错误的。最明显的解决方案是使用break
for (i = 0; i < lim-1; ++i)
{
c = getchar();
if (c == '\n')
break;
if (c == EOF)
break;
s[i] = c;
}或者,如果你假装C没有break,你可以这样做(这并不完全等同,因为如果遇到'\n'或EOF,i的值就不一样了):
for (i = 0; i < lim-1;)
{
c = getchar();
if (c == '\n')
i = lim-1;
else if (c == EOF)
i = lim-1;
else
s[i++] = c;
}或者,您可以使用Pascal方法:
#include <stdbool.h>
...
i = 0;
bool more = i < lim-1;
while (more)
{
c = getchar();
if (c == '\n')
more = false;
else if (c == EOF)
more = false;
else
{
s[i++] = c;
more = i < lim-1;
}
}发布于 2019-08-14 19:51:06
使用goto
i=0;
loop:
if( i >= lim - 1) goto end;
c = getchar();
if(c == '\n') goto end;
if(c == EOF) goto end;
s[i++] = c;
goto loop;
end:没有break,没有goto,只有一个for,仍然没有&&和||。
for (i=0; i < lim - 1 ? ((c=getchar()) == '\n' | c == EOF) == 0 : 0; ++i)
s[i] = c;更新
正如@Jim所指出的,通过使用内部?:显式地设置执行顺序是更好的方法
for (i=0; i >= lim - 1 ? 0 : (c=getchar()) == '\n' ? 0 : c != EOF; ++i)
s[i] = c;https://stackoverflow.com/questions/15865404
复制相似问题