web-dev-qa-db-ja.com

条件で割り当てを使用するのはなぜですか?

多くの言語では、割り当ては条件が合法です。私はこの背後にある理由を理解していませんでした。なぜあなたは書くのですか:

if (var1 = var2) {
  ...
}

の代わりに:

var1 = var2;
if (var1) {
  ...
}
67
lajos

If文よりもループに便利です。

while( var = GetNext() )
{
  ...do something with var 
}

そうでなければ書かなければならないだろう

var = GetNext();
while( var )
{
 ...do something
 var = GetNext();
}
100
Gerald

エラー検出などを伴うことが多いアクションのチェーンで最も便利だと思います。

_if ((rc = first_check(arg1, arg2)) != 0)
{
    report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
    report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
    report error based on new rc
}
else
{
    do what you really wanted to do
}
_

別の方法(条件で割り当てを使用しない)は次のとおりです。

_rc = first_check(arg1, arg2);
if (rc != 0)
{
    report error based on rc
}
else
{
    rc = second_check(arg2, arg3);
    if (rc != 0)
    {
        report error based on new rc
    }
    else
    {
        rc = third_check(arg3, arg4);
        if (rc != 0)
        {
            report error based on new rc
        }
        else
        {
            do what you really wanted to do
        }
    }
}
_

長期にわたるエラーチェックを使用すると、代替手段はページのRHSを実行できますが、条件付き割り当てバージョンでは実行できません。

エラーチェックは、単にチェックするのではなく、「アクション」、つまりfirst_action()second_action()third_action()にすることもできます。つまり、機能が管理しているプロセスのステップをチェックできます。 (ほとんどの場合、使用するコードでは、関数は前提条件チェックの行に沿っているか、関数が機能するために必要なメモリ割り当て、または同様の行に沿っています)。

30

関数を呼び出す場合に便利です。

if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}

もちろん、n = foo();別のステートメントでif(n)が、上記はかなり読みやすいイディオムだと思います。

29
Chris Young

処理するデータまたはエラーを示すフラグ(または完了したこと)を返す関数を呼び出す場合に役立ちます。

何かのようなもの:

while ((c = getchar()) != EOF) {
    // process the character
}

// end of file reached...

個人的にそれは私があまり好きではないイディオムですが、時には代替案はいです。

23
Michael Burr

GCCは、(-Wallを使用して)書き込みを推奨する場合に、意図せずに割り当てを真理値として使用しようとした場合の検出に役立ちます。

if ((n = foo())) {
   ...
}

つまり余分な括弧を使用して、これが本当に必要なものであることを示します。

10
JesperE

このイディオムは、whileステートメントの代わりにifループを記述する場合により便利です。 ifステートメントの場合、説明どおりに分割できます。ただし、この構成体がないと、次のいずれかを繰り返す必要があります。

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

または、ループアンドハーフ構造を使用します。

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

私は通常、ループアンドハーフ形式を好むでしょう。

8
Greg Hewgill

簡単な答えは、 Expression-oriented プログラミング言語はより簡潔なコードを許可するということです。 クエリとコマンドを分離する を強制することはありません。

4
Hugh Allen

たとえば、PHPでは、SQLデータベースの結果をループするのに便利です。

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

これは以下よりもはるかに良く見えます:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}
3
Jeremy Ruten

もう1つの利点は、gdbの使用中です。次のコードでは、シングルステップを実行した場合のエラーコードは不明です。

while (checkstatus() != -1) {
    // process
}

むしろ

while (true) {
    int error = checkstatus();
    if (error != -1)
        // process
    else
        //fail
}

これで、単一のステップで、checkstatus()からの戻りエラーコードが何であるかを知ることができます。

2
plasmixs