Le moyen le plus simple de retourner une valeur booléenne?


124

Je veux juste retourner un booléen basé sur ce qu'il est déjà. Si c'est vrai, faites-le faux. Si c'est faux, rendez-le vrai.

Voici mon extrait de code:

switch(wParam) {

case VK_F11:
  if (flipVal == true) {
     flipVal = false;
  } else {
    flipVal = true;
  }
break;

case VK_F12:
  if (otherVal == true) {
     otherValVal = false;
  } else {
    otherVal = true;
  }
break;

default:
break;
}

Réponses:


341

Vous pouvez inverser une valeur comme ceci:

myVal = !myVal;

donc votre code se réduirait à:

switch(wParam) {
    case VK_F11:
    flipVal = !flipVal;
    break;

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}

7
C'est non seulement le moyen le plus simple, mais aussi le plus propre.
— sharptooth

les deux cas peuvent être fusionnés car ils font la même chose.
— David Allan Finch

1
Est la valeur par défaut: break; vraiment nécessaire? Le commutateur ne se terminera-t-il pas de la même manière sans lui?
— Chris Lutz

12
Par défaut: break; est inutile.
— Rob K

4
Si vous basculez quelque chose de long comme object1-> system1.system2.system3.parameter1, alors il peut être utile d'avoir une macro TOGGLE (a). Cela évite certaines erreurs et rend le tout plus lisible sur des écrans étroits.
— OJW

77

Vous avez clairement besoin d'un modèle d'usine!

KeyFactory keyFactory = new KeyFactory();
KeyObj keyObj = keyFactory.getKeyObj(wParam);
keyObj.doStuff();


class VK_F11 extends KeyObj {
   boolean val;
   public void doStuff() {
      val = !val;
   }
}

class VK_F12 extends KeyObj {
   boolean val;
   public void doStuff() {
      val = !val;
   }
}

class KeyFactory {
   public KeyObj getKeyObj(int param) {
      switch(param) {
         case VK_F11:
            return new VK_F11();
         case VK_F12:
            return new VK_F12();
      }
      throw new KeyNotFoundException("Key " + param + " was not found!");
   }
}

:RÉ

</sarcasm>

9
Nous pourrions probablement ajouter le modèle de singleton pour l'usine aussi.
— Drew

@Orm Parce que tu es un ORM ? :)
— mlvljr

3
Notez la recommandation subtile de passer à Java!
— Escargot mécanique

Eh bien ... je pense que nous avons besoin d'une autre version majeure de C ++ pour celui-ci, peut-être C ++ / 51
— 0x6900

Salut les gars! Je pense que votre approche n'est pas réentrante. Vous avez besoin d'au moins atomic_bool, mieux un mutex ou une file d'attente d'événements. De plus, nous avons besoin d'un modèle d'observateur pour surveiller l'état de val.
— Marco Freudenberger

38

Si vous savez que les valeurs sont 0 ou 1, vous pouvez le faire flipval ^= 1.


1
Pourquoi utiliser un opérateur binaire pour une opération logique? Des odeurs d'obscurcissement inutile pour moi.
— Mark Pim

5
@Mark: Désolé. Je suppose que je suis démodé. Mais cela aide si votre expression de valeur L est vraiment longue, vous n'avez donc pas à la répéter. Vous pouvez également dire flipval ^ = TRUE. Est-ce mieux?
— Mike Dunlavey

6
@Alnitak: Vous avez raison dans certaines circonstances. J'ai vu des gens emballer des morceaux ensemble pour "économiser de l'espace" et agir comme si les instructions pour y accéder ne prenaient pas de place.
— Mike Dunlavey

2
@Albert: ^est l' opérateur exclusif-or . 0^1est 1, et 1^1est 0. C'est la même chose que d'ajouter si vous ignorez le bit de retenue. Ou vous pouvez le considérer comme - si l'un des bits est 1, le résultat est l'inverse de l'autre bit. Ou vous pouvez penser que cela pose la question: ces deux éléments sont-ils différents?
— Mike Dunlavey

1
@MikeDunlavey si vous êtes sur un appareil avec 4M de Flash pour l'espace de code et 3K de SRAM pour l'espace de données, alors c'est une manière justifiée d'agir!
— MM

33

La solution la plus simple que j'ai trouvée:

x ^= true;

11
x = !x;est non seulement plus court, mais aussi plus lisible.
— Rodrigo

13
Notez que par exemple longVariableName ^= true;est clairement plus court que longVariableName = !longVariableName;Et chaque programmeur doit connaître XOR.
— xamid

a ^= bsignifie a = a ^ b, où ^signifie XOR. La notation a °= bpour a = a ° bn'importe quel opérateur °est très courante dans la syntaxe C / C ++ / C #.
— xamid

2
Anecdotique, mais je suis récemment tombé sur la ligne gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value = !gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value;Bien sûr, la chose la plus propre à faire est de l'étendre à plusieurs lignes et d'utiliser des variables temporaires pour stocker les objets, mais elle gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value ^= 1est beaucoup plus lisible, moins sujette aux erreurs et moins de caractères que le code d'origine .
— Vortico du

1
De plus, moins de duplication signifie moins de chances d'oublier de mettre à jour les DEUX côtés de l'équation lors de changements de développement rapides / de longues journées / nuits de codage.
— Katastic Voyage

11

Juste pour information - si au lieu d'un entier, votre champ obligatoire est un seul bit dans un type plus grand, utilisez plutôt l'opérateur 'xor':

int flags;

int flag_a = 0x01;
int flag_b = 0x02;
int flag_c = 0x04;

/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */
flags ^= flag_b;

/* I want to set 'flag_b' */
flags |= flag_b;

/* I want to clear (or 'reset') 'flag_b' */
flags &= ~flag_b;

/* I want to test 'flag_b' */
bool b_is_set = (flags & flag_b) != 0;

9

Cela semble être un free-for-all ... Heh. Voici une autre variation, qui, je suppose, est plus dans la catégorie «intelligente» que quelque chose que je recommanderais pour le code de production:

flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);

Je suppose que ses avantages sont:

  • Très concis
  • Ne nécessite pas de branchement

Et un inconvénient tout aussi évident est

  • Très concis

Ceci est proche de la solution de @ korona utilisant?: Mais fait un (petit) pas plus loin.


2
Par ordre d'opérations, je pense que vous pouvez omettre la parenthèse pour encore plus de concision. : O
— Match

8

Juste parce que ma manière préférée de faire basculer un booléen n'est pas répertoriée ...

bool x = true;
x = x == false;

fonctionne aussi. :)

(oui x = !x;c'est plus clair et plus facile à lire)


6

La solution codegolf'ish serait plus comme:

flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;

2

Je préfère la solution de John T, mais si vous voulez passer au code-golfy, votre déclaration se réduit logiquement à ceci:

//if key is down, toggle the boolean, else leave it alone.
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal);
if(wParam==VK_F11) Break;

//if key is down, toggle the boolean, else leave it alone.
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal);
if(wParam==VK_F12) Break;

Vous n'avez pas à vérifier wParam par rapport à VK_F11 et VK_F12?
— drby


0

Il est clair que vous avez besoin d'une solution flexible capable de prendre en charge les types se faisant passer pour des booléens. Ce qui suit permet cela:

template<typename T>    bool Flip(const T& t);

Vous pouvez ensuite le spécialiser pour différents types qui pourraient prétendre être booléens. Par exemple:

template<>  bool Flip<bool>(const bool& b)  { return !b; }
template<>  bool Flip<int>(const int& i)    { return !(i == 0); }

Un exemple d'utilisation de cette construction:

if(Flip(false))  { printf("flipped false\n"); }
if(!Flip(true))  { printf("flipped true\n"); }

if(Flip(0))  { printf("flipped 0\n"); }
if(!Flip(1)) { printf("flipped 1\n"); }

Non, je ne suis pas sérieux.


0

Pour les entiers avec des valeurs de 0 et 1, vous pouvez essayer:

value = abs(value - 1);

MWE en C:

#include <stdio.h>
#include <stdlib.h>
int main()
{
        printf("Hello, World!\n");
        int value = 0;
        int i;
        for (i=0; i<10; i++)
        {
                value = abs(value -1);
                printf("%d\n", value);
        }
        return 0;
}

0

Juste parce que j'aime remettre en question le code. Je propose que vous puissiez également utiliser le ternaire en faisant quelque chose comme ceci:

Exemple:

bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.