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) {
...
}
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();
}
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).
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.
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.
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.
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.
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 .
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);
}
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 ().