web-dev-qa-db-fra.com

Pourquoi utiliseriez-vous une affectation dans un état?

Dans de nombreuses langues, les missions sont légales. Je n'ai jamais compris la raison derrière cela. Pourquoi écririez-vous:

if (var1 = var2) {
  ...
}

au lieu de:

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

Il est plus utile pour les boucles que pour les instructions if.

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

Qui devrait autrement être écrit

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

Je le trouve très utile dans les chaînes d'actions qui impliquent souvent la détection d'erreurs, etc.

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
}

L'alternative (n'utilisant pas l'affectation dans la condition) est:

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
        }
    }
}

Avec la vérification d'erreur prolongée, l'alternative peut s'écouler du RHS de la page alors que la version d'affectation conditionnelle ne le fait pas.

Les vérifications d'erreurs peuvent également être des "actions" - first_action(), second_action(), third_action() - bien sûr, plutôt que de simples vérifications. Autrement dit, il pourrait s'agir d'étapes vérifiées du processus géré par la fonction. (Le plus souvent dans le code avec lequel je travaille, les fonctions sont dans le sens des vérifications de précondition, ou des allocations de mémoire nécessaires au fonctionnement de la fonction, ou dans le même sens).

30
Jonathan Leffler

C'est plus utile si vous appelez une fonction:

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

Bien sûr, vous pouvez simplement mettre le n = foo (); sur une déclaration distincte alors if (n), mais je pense que ce qui précède est un idiome assez lisible.

29
Chris Young

Cela peut être utile si vous appelez une fonction qui renvoie des données sur lesquelles travailler ou un indicateur pour indiquer une erreur (ou que vous avez terminé).

Quelque chose comme:

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

// end of file reached...

Personnellement, c'est un idiome que je n'aime pas beaucoup, mais parfois l'alternative est plus laide.

23
Michael Burr

GCC peut vous aider à détecter (avec -Wall) si vous essayez involontairement d'utiliser une affectation comme valeur de vérité, au cas où il vous recommanderait d'écrire

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

C'est à dire. utilisez des parenthèses supplémentaires pour indiquer que c'est vraiment ce que vous voulez.

10
JesperE

L'idiome est plus utile lorsque vous écrivez une boucle while au lieu d'une instruction if. Pour une instruction if, vous pouvez la décomposer comme vous le décrivez. Mais sans cette construction, vous devrez soit vous répéter:

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

ou utilisez une structure en boucle et demie:

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

Je préfère généralement la forme en boucle et demie.

8
Greg Hewgill

La réponse courte est que les langages de programmation orientés expression permettent un code plus succinct. Ils ne vous obligent pas à séparer les commandes des requêtes .

4
Hugh Allen

En PHP, par exemple, il est utile pour parcourir les résultats de la base de données SQL:

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

Cela semble beaucoup mieux que:

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

L'autre avantage vient lors de l'utilisation de gdb. Dans le code suivant, le code d'erreur n'est pas connu si nous devions effectuer une seule étape.

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

Plutôt

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

Maintenant, au cours d'une seule étape, nous pouvons savoir quel était le code d'erreur de retour à partir de checkstatus ().

2
plasmixs