Question

Dans de nombreuses langues, les affectations sont légales dans certaines conditions. Je n'ai jamais compris la raison derrière cela. Pourquoi voudriez-vous écrire:

if (var1 = var2) {
  ...
}

au lieu de:

var1 = var2;
if (var1) {
  ...
}
Était-ce utile?

La solution

C'est plus utile pour les boucles que pour les déclarations if.

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

Ce qui devrait autrement être écrit

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

Autres conseils

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 séparée alors si (n), mais je pense que ce qui précède est un idiome assez lisible.

Je le trouve plus utile dans les chaînes d’actions qui impliquent souvent la détection d’erreur, 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 (ne pas utiliser l'affectation dans la condition) est la suivante:

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 un contrôle d'erreur prolongé, l'alternative peut s'exécuter à partir de la RHS de la page alors que la version en affectation conditionnelle ne le fait pas.

Les vérifications d'erreur pourraient également être des "actions" & # 8212; first_action () , second_action () , third_action () & # 8212; bien sûr, plutôt que de simples chèques. C'est-à-dire qu'elles pourraient être vérifiées les étapes du processus géré par la fonction. (Le plus souvent, dans le code avec lequel je travaille, les fonctions se situent dans la lignée des vérifications de pré-condition ou des allocations de mémoire nécessaires au bon fonctionnement de la fonction, ou selon des lignes similaires).

Cela peut être utile si vous appelez une fonction qui renvoie des données à utiliser 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.

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 recommande d'écrire

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

I.e. utilisez des parenthèses supplémentaires pour indiquer que c’est vraiment ce que vous voulez.

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érerais généralement la forme en boucle et demie.

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

En PHP, par exemple, il est utile pour parcourir en boucle 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);
}

L’autre avantage est lié à l’utilisation de gdb. Dans le code suivant, le code d'erreur n'est pas connu si nous devions procéder en une seule étape.

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

Plutôt

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

Maintenant, en une seule étape, nous pouvons savoir quel était le code d'erreur renvoyé par checkstatus ().

La raison en est:

  1. Amélioration des performances (parfois)

  2. Code mineur (toujours)

Prenons un exemple: il existe une méthode someMethod () et une condition if pour vérifier si la valeur renvoyée par la méthode est null . Sinon, vous allez utiliser la valeur de retour à nouveau.

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

Cela gênera la performance puisque vous appelez deux fois la même méthode. Utilisez plutôt:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top