Existe-t-il une différence entre && et & avec bool (s)?

En C ++, existe-t-il une différence entre && (logique) et & (bit à bit) entre bool (s)?

 bool val1 = foo(); bool val2 = bar(); bool case1 = val1 & val2; bool case2 = val1 && val2; 

Les case1 et case2 sont- case2 identiques ou, sinon, comment varient-ils exactement et pourquoi l’un choisirait-il l’un sur l’autre? Est-ce qu’un bitwise et des bools sont portables?

    La norme garantit que false convertit à zéro et true convertit à un sous forme d’entiers:

    4.7 Conversions intégrales

    Si le type de destination est bool, voir 4.12. Si le type de source est bool, la valeur false est convertie en zéro et la valeur true en un.

    Ainsi, dans l’exemple que vous donnez, l’effet est garanti identique et est 100% portable.

    Dans le cas que vous donnez, tout compilateur décent est susceptible de générer un code identique (optimal).

    Cependant, pour les expressions booléennes expr1 et expr2 , il n’est pas vrai que expr1 && expr2 est identique à expr1 & expr2 car && effectue une évaluation “en court-circuit”. C’est-à-dire que si expr1 évalué à false , expr2 ne sera même pas évalué. Cela peut affecter les performances (si expr2 est compliquée) et le comportement (si expr2 a des effets secondaires). (Mais notez que la forme peut être plus rapide si elle évite une twig conditionnelle … Jouer avec ce genre de chose pour des raisons de performance est presque toujours une mauvaise idée.)

    Ainsi, pour l’exemple spécifique que vous donnez, où vous chargez les valeurs dans des variables locales, puis vous les manipulez, le comportement est identique et les performances très probables.

    À mon avis, à moins que vous vous appuyiez spécifiquement sur le comportement de “court-circuit”, vous devriez choisir la formulation qui exprime le plus clairement votre intention. Utilisez donc && pour AND logique et & pour bit AND twiddling, et tout programmeur C ++ expérimenté trouvera votre code facile à suivre.

    Lorsque vous utilisez logical et && , l’expression de droite ne sera pas évaluée si l’expression de gauche est false.

    Beaucoup de code C / C ++ / C # s’appuie sur cela, comme dans: if (p != null && p->Foo()) .

    Pour votre exemple, je voudrais utiliser case2 (et logique). Utilisez uniquement au niveau des bits pour traiter les indicateurs de bits, etc.

    Cependant, si foo () et bar () ne renvoient que bool (0, 1), alors cas1 et cas2 sont identiques.

    Il y a une différence (enfin, deux), bien que vous ne la voyiez pas dans votre exemple.

    “&” effectue une opération binary “AND”, ce qui signifie que 0x1 & 0x1 = 0x1 , mais 0x1 & 0x2 = 0x0 . OTOH, “&&” est un “AND” booléen / logique, ce qui signifie qu’il traite toute valeur non nulle comme un TRUE, donc 0x1 && 0x1 = TRUE (qui est généralement représenté par -1, c’est-à-dire que tous les uns [ou peut-être qu’il est représenté comme 1 en C ++, j’oublie]), tandis que 0x1 && 0x2 = TRUE également.

    De plus, “&&” court-circuite, ce qui signifie que si le premier opérande est FALSE, le second ne sera pas évalué. Ainsi, alors que FALSE & null_pointer->booleanField ==> null pointer exception , FALSE && null_pointer->booleanField = FALSE .

    Il peut y avoir un léger avantage de performance dans l’utilisation des opérations au niveau des bits dans certains cas, mais vous devez généralement utiliser les doubles formes lors de l’évaluation des valeurs booléennes, afin que votre code soit indépendant de la représentation précise des valeurs booléennes VRAI et FAUX.

    Algorithmiquement, il n’y a pas de différence, cependant, l’utilisation de && vous permet de “court-circuiter” le contrôle. C’est-à-dire que pour décider de cas2, si val1 est fausse, le code compilé n’a aucune raison de vérifier la valeur de val2 afin de déterminer la réponse, où cas1 exige que l’AND effectif ait lieu.

    De manière réaliste, un bon compilateur le reconnaîtra et produira le même code … cela dépend de la qualité de votre compilateur.

    && ” est un “ET logique” ET “il évalue la deuxième expression UNIQUEMENT si la première est VRAIE

    & ” est un “ET logique non conditionnel AND” <- (si vous jouez avec des expressions booléennes), il évalue les deux expressions


    MOREOVER “&” est un opérateur ‘au niveau des bits’, ce qui signifie qu’il opère au niveau du bit.

    Cet exemple peut vous aider à mieux comprendre.

     4 = 00000100 // 'four' bit set 5 = 00000101 // 'four' bit and 'one' bit set 00000100 (4) & // AND: only keep bits set in both 00000101 (5) -------- 00000100 (4) 00000100 (4) | // OR: keep bits set in either 00000101 (5) -------- 00000101 (5) 00000100 (4) ^ // EXCLUSIVE OR: keep bits only set in one but not the other 00000101 (5) -------- 00000001 (1) 

    Les opérateurs logiques && et || sont utilisés lors de l’évaluation de deux expressions pour obtenir un seul résultat relationnel. L’opérateur && correspond à l’opération logique booléenne AND. Cette opération a pour résultat vrai si ses deux opérandes sont vrais et faux sinon.

    L’opérateur || correspond à l’opération logique booléenne OU. Cette opération a pour résultat vrai si l’un ou l’autre de ses deux opérandes est vrai et n’est donc fausse que lorsque les deux opérandes sont faux eux-mêmes.

     int a = 0, b = 10; if(a == 1 && (b/a) == 0) cout << "This is okay\n"; // the 2nd expression is never checked as the first one is false cout << "Bingo\n"; if(a == 1 & (b/a) == 0) cout << "This is not okay\n"; // program crashes here trying to divide by zero cout << "Bingo\n"; // this will never get printed