33

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

int c;

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

if (c == ' ') {

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

    {}  // do nothing?

    putchar(' ');

}

putchar(c);

}

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

4

12 に答える 12

49

まったくありません。K&R では、このような何もしないループを見つけることができると思います。

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

while(something());

ループであることを強調するために、別の行にセミコロンを入れることを好む人もいます:

while(something())
  ;

あなたが行ったように、さらに他の人は、内部に何も入れずにブラケットを使用することを好みます:

while(something())
{
}

それはすべて有効です。好きなスタイルを選んで、それを使い続けるだけです。

于 2009-01-15T05:03:00.347 に答える
6

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

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

于 2009-01-15T06:10:08.183 に答える
6

私はそれが完全に受け入れられると思います。

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

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

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

または、次のように書きます。

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

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

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

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

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

于 2009-01-15T05:06:00.887 に答える
5

Well if you really don't like the empty braces, you could refactor that inner loop into

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

This costs one extra comparison though, so a do while loop would be better.

于 2009-01-15T05:10:21.423 に答える
3

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

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

...は、本当に、本当に、費用のかかる待機方法です。OSが提供するのと同じくらい多くのCPUを使用します。これは、readyfalseである限り、他のスレッドが有用な作業を行うためのCPU時間を盗みます。

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

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

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

于 2009-01-15T06:20:40.300 に答える
1

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

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

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

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

これはもっと珍しいことですが、条件1が非常に複雑で混乱する可能性がない場合、またはコードがその寿命の1インチ以内に手動で最適化されている場合に表示されます。最も一般的なケースを最初にしたい。

while(condition) ;

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

 while(condition){
 }

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

于 2009-01-15T06:12:15.917 に答える
1

I would favor:

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

I've also been known to have a procedure named DoNothing specifically for calling in cases like this. It makes it very clear that you really mean to do nothing.

While non-existent loop bodies are perfectly acceptable it should be VERY clear that it's intentional.

于 2009-01-15T05:19:34.183 に答える
1

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

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

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

于 2009-01-15T05:02:59.957 に答える
0

I thinks no problem in it. You can use it, In many situations i prefer it.

于 2009-01-15T05:11:41.907 に答える
0

Well, not really but it depends on your architecture.

if (dosomething()) { ; }

The above is going to constantly be pushing and popping from your local stack, which has a memory overhead. Also, you will also be flushing your processors' pipelines with noop operations.

于 2009-01-15T06:20:32.953 に答える
0

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

于 2009-01-15T05:05:22.370 に答える
-1

An alternative option which hasn't been mentioned yet:

while(condition)
    (void)0;

I really do not prefer to write my loops this way, but I had a TA last semester who did.

于 2009-01-15T06:19:26.123 に答える