11
votes

Utiliser l'affectation comme une expression de condition?

Considérez: xxx

Comment fonctionne l'affectation fonctionne comme une condition?

est-il basé sur une valeur non nulle de la valeur L? < / p>


8 commentaires

Compilez-vous en C ++ ou C?


int war = faux; Si (guerre = vrai) {launknuke (); }


@WTP: Ne comparez jamais un booléen à rien. Un booléen est déjà booléen: si (guerre) launchnuke (); et programmeurs qui affectent true ou false à un non-booléen mérite toutes sortes de Meyham a lancé contre eux.


@David: Où WTP a-t-il comparé un booléen à un booléen?


@Tomalak: Il n'a pas fait, mais si (var = true) était probablement destiné à être si (var == true) . L'écrire comme si (var) en premier lieu aurait soigneusement évité le potentiel = vs. == "confusion.


@Keith: Compte tenu du sujet, je suis assez certain qu'il était ironique.


@George: Acceptez les réponses à vos questions, s'il vous plaît.


@WTP qui a fait ma journée :-)


5 Réponses :


27
votes

C ++ - ISO / CEI 14882: 2003 (E)

[5.17 / 1] code> Il y a plusieurs opérateurs d'affectation, tous groupe de droite à gauche. Tous exigent une lvalue modifiable comme opérande gauche, et le type d'une expression d'affectation est celle de son opérande gauche. Le résultat de l'opération d'affectation est la valeur stockée dans la gauche opérande après la cession a eu lieu strong>; le résultat est une lvalue. p> Blockquote>

Le résultat de l'expression a = 5 code> est 5 code>. P>

[6.4 / 4] code> [..] La valeur d'un état em> qui est une expression est la valeur de la expression, converti implicitement à bool code> strong> pour les déclarations autres que switch code>. [..] p> Blockquote>

conversion A à bool code> a lieu. P>

[4,12 / 1] code> Un rvalue de l'arithmétique, l'énumération, pointeur ou pointeur vers un membre type peut être converti en un rvalue de type bool code>. Une valeur zéro, null valeur de pointeur, ou une valeur de pointeur d'élément de null est converti en false code>; tout autre valeur est convertie en true code>. strong> p> Blockquote>

5 code> convertis en booléen true code>. P>

[6.4.1 / 1] code> Si la condition (6.4) donne le premier vrai est exécuté sous-structure. strong> [..] p> Blockquote>

true code> est traité comme un si code> réussite de l'instruction p>


C - ISO / IEC 9899:. 1999 (E ) h3>

[06.05.16 / 3] code> un opérateur d'affectation stocke une valeur dans l'objet désigné par l'opérande gauche. Une expression d'affectation a la valeur de l'opérande gauche après la cession strong>, mais pas une lvalue. [..] p> Blockquote>

Le résultat de l'expression a = 5 code> est 5 code>. P>

[6.8.4.1/2] code> Dans les deux formes, la première est exécutée si sous-structure de la expression compare différent de 0 strong>. [..] p> Blockquote>

5 code> est traité comme un si code> réussite de l'instruction. P>


Général h2>

code comme ce qui est presque toujours une erreur; probablement l'auteur prévu if (a == 5) {} code>. Cependant, il est parfois délibérée. Vous pouvez voir le code comme ceci: p>

if (x = foo()) {
   cout << "I set x to the result of foo(), which is truthy";
   // ... stuff
}


6 commentaires

Pour vous assurer que ce n'est pas une erreur, vous pouvez écrire si (((A = 5)! = 0) qui est sémantiquement identique au même que si (A = 5) .


0,0 sera-t-il considéré comme une valeur zéro?


@Stan: On dirait zéro pour moi! (Bien que rappelez que le point flottant est inexact.)


Étant donné que la question est étiquetée C et C ++, il pourrait être agréable de mentionner que vous citez C ++, pas C. Le raisonnement est plutôt différent pour les deux.


@Tomalak Geret'kal: Les polices pourraient être un peu plus petites.


@Tomalak Geret'kal: Naah, la réponse est très bonne, mais celles Big Les polices en direction de la tête ont vraiment blesser les yeux :)



1
votes

si (a = x) est équivalent à si (x) en plus de a attribué avec x . Donc, si l'expression x est évaluée à une valeur non nulle, alors si (x) devient simplement si (vrai) . Sinon, il devient si (faux) .

Dans votre cas, car x = 5 , cela signifie que f (a = 5) est équivalent à si (vrai) en plus à A attribué avec 5 .


3 commentaires

Ceci est un peu trompeur: si (a = 5) n'est pas équivalent à si (vrai) car il attribue également A .


-1: si (a = x) 'et si (x)' ne sont pas équivalents, la première expression a un effet secondaire.


@interjay: Je viens de la modifier, lorsque vous commenciez tous les deux.



1
votes

Chaque valeur non nulle sera considérée comme vraie .

de sorte que certaines personnes vous suggèrent d'écrire xxx

pour éviter que vous Faites une erreur == par = .


6 commentaires

La plupart des compilateurs avertiront cette erreur de nos jours.


@Bo Persson: c'est sûrement. Mais certains paresseux aimeraient désactiver l'avertissement, alors en faisons une erreur qu'un avertissement.


-1: Pour moi, c'est laid et ne fournit pas de solution générale.


Je ne suggère pas d'écrire 5 == A . Je suggère d'écrire A == 5 . :) Fais-le; c'est pas difficile. Et si vous éteignez des avertissements, vous méritez tout ce que vous obtenez.


@Tomalak Geret'kal: Eh bien, je suis d'accord avec vous. J'ai donc dit "certaines personnes" mais pas seulement "je". Bien sûr '5 == A' est laid, cependant, Certaines personnes (par exemple mon patron) aide que ... Parfois, vous devez vous rendre.


À mon avis, la construction si (5 == a) {...} est laid, laid, laide, et il est inutile contre des erreurs telles que si (i = j) { ...} . BTW, je n'ai pas répondu.



0
votes

Oui, il est basé sur la valeur zéro / non nulle que A est attribuée. À certaines personnes (moi-même incluses), il est également considéré comme une mauvaise pratique d'avoir des expressions avec des effets secondaires dans votre code, le fragment de code mentionné serait de préférence écrit comme quelque chose comme xxx


1 commentaires

Je pense que c'est bien si c'est si (int A = foo ()) {...} ... Affectation if-scopée.



0
votes

Dans une utilisation plus moderne, vous pouvez parfois voir ce motif utilisé pour gérer en option s: xxx


0 commentaires