C 使用while块什么都不做是件坏事吗?

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循环来跳过所有的空间

我目前正在进行“C编程语言”的练习。以下是我的一个解决方案:

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='';除非