while ブロックを使用して何もしないのは悪いことですか?

StackOverflow https://stackoverflow.com/questions/445700

  •  22-07-2019
  •  | 
  •  

質問

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

int c;

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

if (c == ' ') {

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

    {}  // do nothing?

    putchar(' ');

}

putchar(c);

}

いくつかの解決策を見つけました ここ これは私のものとはまったく異なり、何が起こっているかを追跡するために追加の変数を使用しますが、私はすべてのスペースをスキップするために while ループを使用するだけです。私の解決策は、中括弧の間に何も入れずに while ループを使用するのは少しハック的であるため、少し面倒に感じます。これを行わない正当な理由があるのではないかと考えました。アドバイスをありがとう:-)

役に立ちましたか?

解決

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

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

while(something());

ループであるという事実を補強するために、セミコロンを別の行に配置することを好む人もいます:

while(something())
  ;

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

while(something())
{
}

すべて有効です-好きなスタイルを選択して、それに従うだけです。

他のヒント

あなたの質問は「しばらくのブロックを使って悪いことをすることはありませんか?」 CPUサイクルを無駄にするという観点からも回答することもできます。この場合、答えは「いいえ」です。ユーザーが文字を入力するのを待っている間、プロセスはスリープ状態になるからです。

プロセスは文字が入力された後にのみ起動します。その後、テストが行​​われ、テストに合格すると、つまり、c == ' ' の場合、プロセスは次の文字が入力されるまで再びスリープ状態になります。これは、スペース以外の文字が入力されるまで繰り返されます。

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

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

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

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

または次のように記述します:

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

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

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

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

フォーマット。セミコロンを見落とすのは簡単だと思います。

まあ、空のブレースが本当に気に入らなければ、その内部ループをリファクタリングできます

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

ただし、比較に1回余分なコストがかかるため、do whileループの方が優れています。

手順はそうではないと思いますが、フォーマットはかなり奇妙です。問題はありません:

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

(つまり、意図的にボディがないことを示す)

私は好む:

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

また、このような場合に呼び出すためのDoNothingという名前のプロシージャがあることもわかっています。あなたが本当に何もしないことを本当に意味していることが非常に明確になります。

存在しないループ本体は完全に受け入れられますが、意図的なものであることは非常に明確でなければなりません。

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

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

...は、本当に、本当に、高価な待機方法です- ready がfalseである限り、OSが与えるだけのCPUを使用し、CPU時間を盗みます他のスレッドが有用な作業を行っている可能性があります。

ただし、ループは何もしていない

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

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

このようなコードを使用しました。状況が許せば、実際に使用しない理由はないと思います。

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

標準的な方法—太古の昔から使用されていました。たとえば、リヨンの本をご覧ください—

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

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

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

かなり一般的ではありませんが、 condition-1 が非常に複雑なため、それを否定して混乱を招かないようにするか、コードを手動で最適化した場合に表示されます人生の1インチ以内に、最も一般的なケースを最初に望むようにします。

while(condition) ;

formは、よくある面倒なタイプミスであるため、慎重に避けるべきです。意図的にそれを行ったことを明確にする必要があります。空の中括弧

 while(condition){
 }

またはそのバリアントは、十分に目立たないか、さらに悪いことに他のタイプミスにつながるため、トラブルでもあります。

まあ、そうではありませんが、アーキテクチャによって異なります。

if (dosomething()) { ; }

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

まだ言及されていない代替オプション:

while(condition)
    (void)0;

このようにループを書くことは本当に好きではありませんが、最後の学期にTAを作成しました。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top