web-dev-qa-db-ja.com

C「for」ループ内の複数の条件

このコードに出会いました。通常、「&&」または「||」を使用しますforループで複数の条件を分離しますが、このコードではコンマを使用してこれを行います。

驚いたことに、条件の順序を変更すると、出力が変化します。

#include<stdio.h>

int main() {
    int i, j=2;

    for(i=0; j>=0,i<=5; i++)
    {
         printf("%d ", i+j);
         j--;
    }
    return 0;
}

出力= 2 2 2 2 2 2

#include<stdio.h>

int main(){
    int i, j=2;

    for(i=0; i<=5,j>=0; i++)
    {
         printf("%d ", i+j);
         j--;
    }
    return 0;
}

出力= 2 2 2

誰かがその理由を説明できますか?最後のコンマ区切りの条件のみをチェックしているようです。

26
Prateek

コンマ演算子は、すべてのオペランドを評価し、最後のオペランドの値を生成します。つまり、基本的にどのような条件を記述してもfirst、は無視され、secondの1つだけが重要になります。

for (i = 0; j >= 0, i <= 5; i++)

したがって、と同等です

for (i = 0; i <= 5; i++)

コードの作成者が意図したものである場合とそうでない場合があります-これをプロダクションコードではないことを望みます。代わりに&&演算子を使用する必要がありました。

53
user529758

もちろん、最初に言ったことは正しいです。C 論理演算子&&および||は通常、条件を「接続」するために使用するものです(trueまたはfalseとして評価できる式)。コンマ演算子は論理演算子ではないため、他のユーザーが説明しているように、この例でコンマ演算子を使用しても意味がありません。あなたはそれを使用することができますfor自体でステートメントを「連結」します。iでjをすべて初期化および更新できます。または otherways でコンマ演算子を使用します

#include <stdio.h>

int main(void)  // as std wants
{
  int i, j;

  // init both i and j; condition, we suppose && is the "original"
  // intention; update i and j
  for(i=0, j=2; j>=0 && i<=5; i++, j--)
  {
       printf("%d ", i+j);
  }
  return 0;        
}
6
ShinTakezou

コンマ式は、last(たとえば、右端)式の値を取ります。

したがって、最初のループでは、唯一の制御式はi<=5;およびj>=0は無視されます。

2番目のループでは、j>=0はループを制御し、i<=5は無視されます。


reason...については理由はありません。このコードはwrongです。コンマ式の最初の部分は、プログラマを混乱させることを除いてnothingを行います。真面目なプログラマーがこれを書いた場合、彼らは自分自身を恥じ、キーボードを取り消す必要があります。

5
abelenky

このコードを使用しないでください。明らかにそれを書いた人は言語の基本的な誤解を持ち、信頼できません。表現:

j >= 0, i <= 5

「j> = 0」を評価し、それを捨てて何もしません。次に、「i <= 5」を評価し、それだけをループの終了条件として使用します。コンマ演算子canは、左側のオペランドに副作用がある場合にループ条件で有意義に使用されます。次のようなものが頻繁に表示されます。

for (i = 0, j = 0; i < 10; ++i, ++j) . . .

この場合、追加の初期化ステートメントと増分ステートメントに潜入するためにコンマが使用されます。しかし、示されているコードはそれを行っていません。

3

Wikipedia は、カンマ演算子の機能を示します。

「CおよびC++プログラミング言語では、カンマ演算子(トークン,)は、最初のオペランドを評価して結果を破棄し、次に2番目のオペランドを評価してこの値(および型)を返す二項演算子です。

3
tafa

Cにはコンマ演算子と呼ばれる演算子があります。各式を順番に実行し、最後のステートメントの値を返します。また、 シーケンスポイント です。つまり、各式は、&& または ||

2

クロッカー氏の回答を完了し、++または-演算子に注意してください。ループに影響を与える可能性があります。たとえば、コースでこれに似たコードを見ました:

for(int i=0; i++*i<-1, i<3; printf(" %d", i));

結果は$ 1 2 $になります。したがって、最初のステートメントはループに影響を与えますが、次の結果はゼロになります。

for(int i=0; i<3; printf(" %d", i));
0
MSN