C 使用while块什么都不做是件坏事吗?
我目前正在进行“C编程语言”的练习。以下是我的一个解决方案:C 使用while块什么都不做是件坏事吗?,c,while-loop,C,While Loop,我目前正在进行“C编程语言”的练习。以下是我的一个解决方案: int c; while ((c=getchar()) != EOF) { if (c == ' ') { while ((c = getchar()) == ' ') {} // do nothing? putchar(' '); } putchar(c); } 我发现了一些与我完全不同的解决方案,并使用了一个额外的变量来跟踪正在发生的事情,而我只是使用了一个while循环来跳过所有的空间
int c;
while ((c=getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ')
{} // do nothing?
putchar(' ');
}
putchar(c);
}
我发现了一些与我完全不同的解决方案,并使用了一个额外的变量来跟踪正在发生的事情,而我只是使用了一个while循环来跳过所有的空间。我的解决方案感觉有点凌乱,因为在花括号之间有一个while循环却什么都没有,这似乎有点骇人。我想知道是否有什么好的理由不这样做?谢谢你的建议:-)我不认为这个过程是正确的,但是你的格式很奇怪。这没有什么错:
/* Eat spaces */
while ((c = getchar()) == ' ');
(也就是说,表示有意不存在实体)一点也不——我相信你会在K&R中发现类似的do nothing循环,所以这是最正式的 这是个人偏好的问题,但我更喜欢我的“什么都不做”循环:
while(something());
while ((c = getchar()) == ' ') {
//no processing required for spaces
}
其他人更喜欢分号放在单独的一行上,以强调它是一个循环:
while(something())
;
还有一些人喜欢使用括号,里面没有任何内容,正如您所做的:
while(something())
{
}
所有这些都是有效的-您只需选择您喜欢的样式并坚持使用即可。我使用过这样的代码。如果情况允许,我认为没有任何理由不使用它。我认为这是完全可以接受的 我要么写:
//skip all spaces
while ((c = getchar()) == ' ') {}
这一行代码的作用是一样的
或者我会这样写:
while(something());
while ((c = getchar()) == ' ') {
//no processing required for spaces
}
使其与代码的其他格式相匹配
就我个人而言,我不喜欢这部电影
while ((c = getchar()) == ' ');
格式。我认为很容易忽略分号。如果你真的不喜欢空括号,你可以将内部循环重构为
while (c == ' ') {c = getchar();}
不过,这需要额外进行一次比较,所以do-while循环会更好。我认为这没有问题。您可以使用它,在许多情况下我更喜欢它。我喜欢:
while ((c = getchar()) == ' ') /* Eat spaces */;
我还知道有一个名为DoNothing的过程专门用于在这种情况下调用。很明显,你真的什么都不想做
虽然不存在的循环体是完全可以接受的,但应该非常清楚这是故意的。您的问题“使用While块做什么都不是坏事吗?”也可能会以浪费CPU周期的方式得到回答。在这种情况下,答案是“否”,因为进程将在等待用户输入字符时休眠
该进程只有在输入字符后才会唤醒。然后将进行测试,如果测试通过,即c=='',则进程将再次进入休眠状态,直到输入下一个字符。这将重复进行,直到输入一个非空格字符。自古以来使用的标准方式是
while(condition) // Here's the whole thing
; // empty body.
事实上,通常“单独行上的半彩色”约定用于null语句。例如,你偶尔会看到
if( condition-1)
;
else if (condition-2)
stmt;
else {
// do stuff here
}
这是非常罕见的,但是出现在条件1非常复杂的地方,因此您不想否定它并造成混淆,或者代码在其生命周期的一英寸内进行了手动优化,因此您首先需要最常见的情况
形式是要刻意避免的,因为这是一个常见且恼人的打字错误:你应该清楚地表明你是故意的。空括号
while(condition){
}
或者它的变体也很麻烦,因为它们要么不够突出,要么更糟,导致其他打字错误。一个尚未提及的替代选项:
while(condition)
(void)0;
我真的不喜欢这样写我的循环,但上学期我有个助教,他这样做了。嗯,不太喜欢,但这取决于你的架构
if (dosomething()) { ; }
上面的代码将不断地从本地堆栈中推送和弹出,这会增加内存开销。此外,您还将使用noop操作刷新处理器的管道。A
,而这可能是一件坏事:
while(!ready) {
/* Wait for some other thread to set ready */
}
。。。这是一种非常非常昂贵的等待方式——只要ready
为false,它将使用操作系统提供的CPU,占用其他线程可以执行有用工作的CPU时间
但是,您的循环不是什么都不做:
while ((c = getchar()) == ' ')
{}; // skip
。。。因为它在每次迭代中都调用getchar()
。因此,正如所有人都同意的那样,您所做的一切都很好。啊,我不知道我可以这样格式化它,哈哈:)谢谢!很好地利用评论。我倾向于避免使用空while循环。一开始它看起来像是一个打字错误,所以在我意识到它是故意的之前,我必须看两遍,然后再看第三遍,弄清楚它是干什么的。在我看来,它们不那么可读。可读性确实是主观的。我总是把大括号放在我能放的地方,所以这会在我的代码库中非常明显地突出出来。+1我对分号发表了类似的看法,但是你的更深入。没有一个有能力的C程序员编写不测试EOF的输入循环。我唯一要做的更改是在注释前面加上分号。你需要担心如果内部while循环遇到EOF会发生什么。此时,您可能会输出字符0xFF(y-umlaut)作为最后一个字符。如果外环的主体缩进,它也会更清晰。为什么不“继续;”对于循环体?我更喜欢一行上的分号,正如大师K&R所描述的那样。@Jonathan:这不是我的主意:-)我不这样写循环。我倾向于把一个“continue”放在一个空循环上:“while(foo)continue;”。我想这会让读者更清楚地看到循环的不可操作性,但这只是一个很小的风格问题,从来没有想过。好主意,liw.fi!在另一个帖子中,有人指出谷歌风格的指南正式推荐{}
或继续代码>,因为分号本身可能看起来像do while循环的结尾。更好的方法可能是:执行{c=getchar();}while(c='';除非