부울 값을 뒤집는 가장 쉬운 방법은 무엇입니까?


124

이미 무엇인지에 따라 부울을 뒤집고 싶습니다. 그것이 사실이라면-거짓으로 만드십시오. 거짓이라면-사실로 만드십시오.

다음은 내 코드 발췌입니다.

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;
}

답변:


341

다음과 같이 값을 뒤집을 수 있습니다.

myVal = !myVal;

따라서 코드는 다음과 같이 단축됩니다.

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

    case VK_F12:
    otherVal = !otherVal;
    break;

    default:
    break;
}

7
이것이 가장 쉬울뿐만 아니라 가장 깨끗한 방법입니다.
sharptooth

두 케이스는 동일한 작업을 수행하므로 병합 될 수 있습니다.
David Allan Finch

1
기본값 : break; 정말 필요한가요? 스위치가 없으면 똑같이 끝나지 않을까요?
Chris Lutz

12
기본값 : break; 불필요합니다.
Rob K

4
object1-> system1.system2.system3.parameter1과 같이 장황한 것을 토글하는 경우 TOGGLE (a) 매크로를 사용하는 것이 도움이 될 수 있습니다. 이렇게하면 실수를 방지하고 좁은 화면에서 더 쉽게 읽을 수 있습니다.
OJW

77

분명히 공장 패턴이 필요합니다!

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!");
   }
}

:디

</sarcasm>

9
우리는 아마도 팩토리에 대한 싱글 톤 패턴을 추가 할 수있을 것입니다.
Drew

@Orm 왜 당신은 ORM 입니까? :)
mlvljr

3
Java로 전환하라는 미묘한 권장 사항에 유의하십시오!
기계 달팽이

음 ... 나는 할 수있다, 우리는이 하나 ++ C의 또 다른 주요 릴리스가 필요하다고 생각 C ++ / 51
0x6900

얘들 아! 나는 당신의 접근 방식이 재진입이 아니라고 생각합니다. 최소한 atomic_bool이 필요합니다. 뮤텍스 나 이벤트 큐가 더 좋습니다. 또한 val의 상태를 모니터링하려면 관찰자 패턴이 필요합니다.
Marco Freudenberger 2017 년

38

값이 0 또는 1 인 것을 알고 있다면 flipval ^= 1.


1
논리 연산에 비트 연산자를 사용하는 이유는 무엇입니까? 쓸데없는 난독 화 냄새.
Mark Pim

5
@ 마크 : 죄송합니다. 내가 구식 인 것 같아요. 그러나 L- 값 표현이 정말 길면 도움이되므로 반복 할 필요가 없습니다. 또한 flipval ^ = TRUE라고 말할 수 있습니다. 그게 더 낫습니까?
Mike Dunlavey

6
@Alnitak : 어떤 상황에서는 당신 말이 맞아요. 나는 어떤 사람들이 "공간을 절약"하기 위해 비트를 모아서 그것들에 접근하라는 지시가 공간을 차지하지 않는 것처럼 행동하는 것을 보았다.
Mike Dunlavey

2
@Albert는 : ^은 IS 배타적 논리합 연산자. 0^1이다 1, 그리고 1^1이다 0. 캐리 비트를 무시하면 추가하는 것과 같습니다. 또는이를 다음과 같이 생각할 수 있습니다. 두 비트 중 하나가 1이면 결과는 다른 비트의 역입니다. 또는 질문을하는 것으로 생각할 수 있습니다.이 두 비트가 다른가요?
Mike Dunlavey 2013

1
@MikeDunlavey 만약 당신이 코드 공간을 위해 4M의 Flash와 데이터 공간을 위해 3K의 SRAM을 가진 장치를 사용한다면 그것은 정당한 행동 방식입니다!
MM

33

내가 찾은 가장 쉬운 솔루션 :

x ^= true;

11
x = !x;짧을뿐만 아니라 더 읽기 쉽습니다.
Rodrigo

13
eg longVariableName ^= true;는 분명히 더 짧으며 longVariableName = !longVariableName;모든 프로그래머는 XOR을 알아야합니다.
xamid

a ^= b의미 a = a ^ b, 여기서 ^XOR을 의미합니다. 모든 연산자 a °= ba = a ° b대한 표기법 은 °C / C ++ / C # 구문에서 매우 일반적입니다.
xamid

2
일화이지만 최근에 한 줄을 gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value = !gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value;보았습니다 물론 가장 깨끗한 방법은 여러 줄로 확장하고 임시 변수를 사용하여 개체를 저장하는 것이지만 gRackWidget->modules->first().lights[PATTERN1_LIGHT + i].value ^= 1원본 코드보다 훨씬 읽기 쉽고 오류가 적으며 문자 수가 적습니다. .
Vortico

1
또한 중복이 적다는 것은 빠른 개발 변경 / 긴 낮 / 밤 코딩 중에 방정식의 양쪽을 업데이트하는 것을 잊을 가능성이 적다는 것을 의미합니다.
Katastic Voyage 2017

11

정보를 위해-정수 대신 필수 필드가 더 큰 유형 내에서 단일 비트 인 경우 대신 '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

이것은 모두를위한 자유인 것 같습니다. 다음은 프로덕션 코드에 권장하는 것보다 "영리한"범주에 더 많은 다른 변형이 있다고 생각합니다.

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

장점은 다음과 같습니다.

  • 매우 간결
  • 분기가 필요하지 않습니다.

그리고 명백한 단점은

  • 매우 간결

이것은? :를 사용하는 @korona의 솔루션에 가깝지만 한 단계 더 나아갔습니다.


2
연산 순서에 따라 더 간결하게 괄호를 생략 할 수 있다고 생각합니다. : O
Drew

8

부울을 토글하는 내가 가장 좋아하는 이상한 공 방법이 나열되지 않기 때문에 ...

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

너무 작동합니다. :)

(예, x = !x;더 명확하고 읽기 쉽습니다)


6

codegolf'ish 솔루션은 다음과 같습니다.

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

2

나는 John T의 솔루션을 선호하지만 모든 코드 골피를 원한다면 논리적으로 다음과 같이 줄입니다.

//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;

VK_F11 및 VK_F12에 대해 wParam을 확인할 필요가 없습니까?
drby


0

분명히 부울로 가장하는 유형을 지원할 수있는 유연한 솔루션이 필요합니다. 다음은이를 허용합니다.

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

그런 다음 부울 인 척할 수있는 여러 유형에 대해이를 특수화 할 수 있습니다. 예를 들면 :

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

이 구성을 사용하는 예 :

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"); }

아니, 진지하지 않아.


0

값이 0과 1 인 정수의 경우 다음을 시도 할 수 있습니다.

value = abs(value - 1);

C의 MWE :

#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

나는 질문 코드를 좋아하기 때문에. 다음과 같이하여 삼항을 사용할 수도 있습니다.

예:

bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.