web-dev-qa-db-ja.com

whileブロックを使用して、悪いことを何もしていませんか?

私は現在、「Cプログラミング言語」の演習に取り組んでいます。これが私の解決策の1つです:

int c;

while ((c=getchar()) != EOF) {

if (c == ' ') {

    while ((c = getchar()) == ' ')

    {}  // do nothing?

    putchar(' ');

}

putchar(c);

}

私はいくつかの解決策を見つけました ここ 私のものとはまったく異なり、何が起こっているかを追跡するために追加の変数を使用しますが、whileループを使用してすべてのスペースをスキップします。中括弧の間に何もないwhileループがあるのは少しハックなように見えるので、私のソリューションは少し厄介に感じます。これをしない正当な理由があるかどうか疑問に思いましたか?アドバイスをありがとう:-)

24
maximo

まったくそうではありません-K&Rでこのような何もしないループが見つかると思いますので、それはほぼ公式です。

それは個人的な好みの問題ですが、私はこのような何もしないループを好みます:

while(something());

他の人は、それがループであるという事実を補強するために、セミコロンを別の行に置くことを好みます:

while(something())
  ;

さらに他の人は、あなたがしたように、中に何も入っていないブラケットを使用することを好みます:

while(something())
{
}

それはすべて有効です-あなたはただあなたが好きなスタイルを選んでそれに固執する必要があるでしょう。

38
Kyle Cronin

あなたの質問「whileブロックを使用して悪いことを何もしていませんか?」 CPUサイクルの浪費という観点からも答えられるかもしれません。この場合、答えは「いいえ」です。これは、ユーザーが文字を入力するのを待つ間、プロセスがスリープするためです。

このプロセスは、文字が入力された後にのみウェイクアップします。次に、テストが実行され、テストに合格した場合、つまりc == ''の場合、次の文字が入力されるまで、プロセスは再びスリープ状態になります。これは、スペース以外の文字が入力されるまで繰り返されます。

6
jeffD

完全に受け入れられると思います。

私はそれを書くでしょう:

//skip all spaces
while ((c = getchar()) == ' ') {} 

この1行のコードが1つのことを行うことを明確にするためです。

または私はそれをこのように書くでしょう:

while ((c = getchar()) == ' ') {
    //no processing required for spaces
}

コードの残りの形式と一致するようにします。

個人的に、私はのファンではありません

while ((c = getchar()) == ' ');

フォーマット。セミコロンは見落としやすいと思います。

4
Chad DeShon

空の中括弧が本当に気に入らない場合は、その内側のループをリファクタリングして

while (c == ' ') {c = getchar();}

ただし、これには1つの追加の比較が必要になるため、dowhileループの方が適しています。

4
Cebjyre

手順は違うと思いますが、フォーマットがかなりおかしいです。何も悪いことはありません:

/* Eat spaces */
while ((c = getchar()) == ' ');

(つまり、意図的に体がないことを示します)

2
Dustin

私は好む:

while ((c = getchar()) == ' ') /* Eat spaces */;

また、このような場合に呼び出すためのDoNothingという名前のプロシージャがあることも知られています。それはあなたが本当に何もしないつもりであることを非常に明確にします。

存在しないループ本体は完全に許容されますが、意図的であることを明確にする必要があります[〜#〜] very [〜#〜]

1
Loren Pechtel

おそらく何もしないwhile悪いことです:

_while(!ready) {
   /* Wait for some other thread to set ready */
}
_

...は、本当に、本当に、費用のかかる待機方法です。readyがfalseである限り、OSが提供するのと同じ量のCPUを使用し、他のスレッドが使用するCPU時間を盗みます。役に立つ仕事をしている可能性があります。

ただし、ループはnot何もしていません:

_while ((c = getchar()) == ' ')
    {};  // skip
_

...すべての反復でgetchar()を呼び出しているためです。したがって、他のすべての人が同意しているように、あなたがしたことは問題ありません。

1
slim

私はこのようなコードを使用しました。状況に応じて使用しない理由はないと思います。

0
recursive

何の問題もないと思います。あなたはそれを使うことができます、多くの状況で私はそれを好みます。

0
Nakul Chaudhary

太古の昔から使用されている標準的な方法は、たとえばライオンズの本を見てください。

while(condition)       // Here's the whole thing
    ;                  // empty body.

実際、一般に、「別行の半色」規則はnullステートメントに使用されます。たとえば、たまに表示されます

if( condition-1)
     ;
else if (condition-2)
     stmt;
else {
     // do stuff here
}

それはもっと珍しいことですが、condition-1が非常に複雑であるため、それを否定したくない場合や混乱を招く可能性がある場合、またはコードが1インチ以内に手動で最適化されている場合に表示されますあなたが最初に最も一般的なケースが欲しいように、その人生の。

ザ・

while(condition) ;

それは一般的で厄介なタイプミスであるため、フォームは惜しみなく避ける必要があります。意図的にそれを行ったことを明確にする必要があります。空の中括弧

 while(condition){
 }

またはその亜種も、十分に目立たないか、さらに悪いことに他のタイプミスにつながるため、問題があります。

0
Charlie Martin

まあ、実際にはそうではありませんが、それはあなたのアーキテクチャに依存します。

if (dosomething()) { ; }

上記は、メモリのオーバーヘッドがあるローカルスタックから絶えずプッシュおよびポップします。また、noop操作でプロセッサのパイプラインをフラッシュします。

0
thesmart