C에서 부울 값 사용


답변:


1049

최선에서 최악으로 :

옵션 1 (C99)

#include <stdbool.h>

옵션 2

typedef enum { false, true } bool;

옵션 3

typedef int bool;
enum { false, true };

옵션 4

typedef int bool;
#define true 1
#define false 0

설명

  • 옵션 1은 C99를 사용하고 "표준 방식"인 경우에만 작동합니다. 가능하면 이것을 선택하십시오.
  • 옵션 2, 3 및 4는 실제로 동일한 동작을합니다. # 2와 # 3은 #defines를 사용하지 않습니다. 제 생각에는 더 좋습니다.

당신이 미정이라면, 1 번으로 가십시오!


1
왜 그들이 최악의 선택에 가장 적합한 지 자세히 설명 할 수 있습니까 ?
— endolith

1
@endolith <stdbool.h> bool컴파일러가 선택한 정렬, 최적화 및 저장 방법 은 부울 값의 의도 된 목적에보다 적합 할 수 있습니다 int(즉, 컴파일러 는와 bool다르게 구현하도록 선택할 수 있음 int). 운이 좋으면 컴파일 타임에 엄격한 유형 검사가 발생할 수도 있습니다.
— blubberdiblub

1
왜 사용 int을위한 bool? 낭비입니다. 사용하십시오 unsigned char. 또는 C의 builtin을 사용하십시오 _Bool.
— 신체 없음

@NoBody 더 작은 유형을 사용하면 메모리를 절약 할 수 있지만 더 빠를 수는 없습니다. 종종 작은 크기 대신 프로세서의 기본 단어 크기를 사용하는 것이 더 빠릅니다. 컴파일러가 올바르게 정렬하기 위해 비트 시프트를해야 할 수도 있습니다.
— Ted Klein Bergman

240

C의 부울에 대한 몇 가지 생각 :

나는 inttypedef 또는 특별한 정의 또는 참 / 거짓 값에 대한 열거없이 평범한 부울 유형으로 일반을 사용하기에 충분히 나이가 들었습니다. 부울 상수와 비교하지 않는 아래의 제안을 따르는 경우 어쨌든 0/1 만 사용하여 플래그를 초기화해야합니다. 그러나 이러한 접근은 현대에 너무 반동적 인 것으로 간주 될 수 있습니다. 이 경우에는 반드시<stdbool.h> 최소한 표준화의 이점이 있으므로 합니다.

부울 상수가 무엇이든, 초기화에만 사용하십시오. 절대로 같은 것을 쓰지 마십시오

if (ready == TRUE) ...
while (empty == FALSE) ...

이것들은 항상 더 선명한 것으로 대체 될 수 있습니다

if (ready) ...
while (!empty) ...

이것들은 실제로 합리적이고 이해하기 쉽게 소리내어 읽을 수 있습니다.

부울 변수에 긍정적 인 이름을 지정하십시오 (예 : full대신) notfull. 후자는 쉽게 읽기 어려운 코드로 이어집니다. 비교

if (full) ...
if (!full) ...

와

if (!notfull) ...
if (notfull) ...

전자쌍은 자연스럽게 !notfull읽히지 만, 그대로 읽기가 어려우며,보다 복잡한 부울 식에서는 훨씬 나빠집니다.

부울 인수는 일반적으로 피해야합니다. 이와 같이 정의 된 함수를 고려하십시오

void foo(bool option) { ... }

함수 본문 내에서 인수가 의미하는 것이 매우 명확하고 편리하고 의미있는 이름이 있기 때문입니다. 그러나 통화 사이트는 다음과 같습니다

foo(TRUE);
foo(FALSE):

여기서 함수 정의 나 선언을 항상 보지 않고 매개 변수의 의미를 알 수는 없으며 부울 매개 변수를 더 추가하면 더 악화됩니다. 나도 제안한다

typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);

또는

#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }

두 경우 모두 통화 사이트는 다음과 같습니다.

foo(OPT_ON);
foo(OPT_OFF);

독자는의 정의를 방해하지 않으면 서 적어도 이해의 기회를 갖습니다 foo.


1
그리고 두 변수가 동일한 지 어떻게 비교합니까? 부울 상수를 사용하지 않는 것은 좋지만 상수가 아닌 것을 비교할 때 문제를 해결하지는 않습니다.
— Baruch

저를 용서하십시오. 그러나 나는 그 질문을 이해하지 못합니다. 두 부울 변수를 동등하게 비교하는 방법을 묻고 있습니까? 그렇다면 a == b작동 하지 않습니까?
— Dale Hagglund

5
@ Kenji 당신이 말하는 것은 사실이지만, 사실과 동등한 것으로 다른 값을 사용하는 것은 거의 항상 나쁜 생각이라고 생각합니다. 가정, 귀하의 예제에서 그래서 a하고 b0부터 카운트, 내가 권하고 싶습니다 a > 0 == b > 0대신. 0이 아닌 임의의 값의 진실성을 이용한다고 주장하면와 !!var같은 부울 0/1 값을 생성 var하므로 글을 쓸 수 !!a == !!b는 있지만 독자는 다소 혼란 스럽습니다.
— 데일 해글 런드

3
!a == !b또한 동등성을 테스트하기에 충분하며, 0이 아닌 값은 0이되고 0은 1이됩니다.
— ryanpattison

5
@rpattiso 물론 그렇습니다. 그러나 !!a"부울이 아닌 값을 동등한 값 !a으로 변환"으로 읽는 반면 "부울 변수 a를 논리적으로 반전"으로 읽는 것 같습니다 . 특히 논리적 반전이 필요한 특정 이유를 찾고 싶습니다.
— Dale Hagglund


74

내가 사용한 버전은 다음과 같습니다.

typedef enum { false = 0, true = !false } bool;

false는 하나의 값만 갖지만 논리적 true는 많은 값을 가질 수 있지만 기술은 true를 컴파일러가 false와 반대로 사용할 것으로 설정합니다.

이것은 누군가가 다음과 같은 것을 코딩하는 문제를 처리합니다.

if (true == !false)

나는 이것이 좋은 습관이 아니라는 것에 동의 할 것이지만, "true =! false"를 수행하는 한 번의 비용으로 그 문제를 제거합니다.

[편집] 결국 나는 사용했다 :

typedef enum { myfalse = 0, mytrue = !myfalse } mybool;

정의 true하고 있던 다른 체계와 이름 충돌을 피하기 위해false . 그러나 개념은 동일합니다.

[편집] 정수를 부울로 변환하는 방법 :

mybool somebool;
int someint = 5;
somebool = !!someint;

첫 번째 (가장 오른쪽)! 0이 아닌 정수를 0으로 변환 한 다음 두 번째 (가장 왼쪽)! 0을 myfalse값으로 변환합니다 . 독자가 제로 정수를 변환하는 연습으로 남겨 두겠습니다.

[편집] 기본값이 같더라도 특정 값이 필요할 때 열거 형에 값을 명시 적으로 설정하는 것이 내 스타일입니다. 예 : false는 0이어야하기 때문에 false = 0,대신 사용하십시오.false,


5
또한 열거 형을 사용하는 또 다른 이점은 IDE 통합이다 - true, false및 bool강조 표시됩니다 대부분의 IDE의 그들은 반대로 열거 값과 타입 정의, 때문에 #defines거의 이제까지 구문 강조 표시됩니다.

호기심 : 실제로 작동하는지 여부를 무시하고 열거 형이 동일한 열거 형 의 이전 값을 참조 할 수 있도록 유효한 C (99+) 입니까?

@ tgm1024 gcc -ansi -pedantic -Wall는 경고를 제공하지 않으므로 신뢰합니다 gcc. 이것이 효과가 있다면 c89잘 작동합니다 c99.
— yyny

1
"false에는 하나의 값만 있기 때문에 논리적 인 true에는 많은 값이있을 수 있지만 기술은 true를 컴파일러가 false와 반대로 사용할 것입니다." 부정 연산자는 !단지 값을 반환 할 수 있습니다 0및 1그래서 true = !false항상 할당 값 1이 방법은 여분의 안전을 이상 제공하지 않습니다 것입니다 typedef enum { false, true } bool;.
— user694733

1
내가 찾은 것은 C90 (6.3.3.3 단항 산술 연산자)입니다. "피연산자의 값이 0과 같지 않으면 논리 부정 연산자!의 결과는 0입니다. 피연산자의 값이 0과 비교하면 1입니다. 결과의 형식은 int입니다.! E 식은 (O == E)와 같습니다. " 이는 표준 C를 지원한다고 주장한 모든 컴파일러를 포괄해야합니다. 컴파일러는 관찰 가능한 동작 (예 : 등 if(!value))에 중요하지 않은 경우이 규칙을 법적으로 무시할 수 있지만이 경우에는 예외가 적용되지 않습니다.
— user694733


30

먼저 첫 번째 것들. C, 즉 ISO / IEC 9899는 현재 19 년 동안 부울 유형이었습니다 . 이 질문을 방문 할 때 아마추어 / 학술 / 전문 부품이 결합 된 C 프로그래밍 경력 의 예상 시간보다 더 긴 시간 입니다. 광산은 아마도 1-2 년 정도를 능가합니다. 그것은 평균적인 독자가 C에 대해 전혀 아무것도 배우지 않았을 때 C는 실제로 부울 데이터 유형을 가졌음을 의미합니다 .

데이터 유형에 대해서는 #include <stdbool.h>, 사용 true, false및 bool. 아니면, 사용에 포함되지 않습니다 _Bool, 1그리고 0대신합니다.


이 스레드에 대한 다른 답변에서 다양한 위험한 관행이 촉진됩니다. 나는 그것들을 다룰 것이다 :

typedef int bool;
#define true 1
#define false 0

19 년 이내에 C를 배운 캐주얼 리더 bool는 실제 bool 데이터 유형을 참조하고 비슷하게 동작 할 것으로 예상 하지만 그렇지 않습니다! 예를 들어

double a = ...;
bool b = a;

C99으로 bool/ _Bool, b에 설정됩니다 false IFF는 a 제로이었다 true그렇지. C11 6.3.1.2p1

  1. 스칼라 값이로 변환 될 때 값이 _Bool0과 비교되면 결과는 0입니다. 그렇지 않으면 결과는 1입니다. 59)

각주

59) NaN은 0과 같지 않으므로 1로 변환됩니다.

으로 typedef장소에서의이 double강제 변환 될 수 int의 두 배의 값이 범위 내에없는 경우는 - int1, 행동이 정의되어 있지 않습니다 .

if true및 false에 선언 된 경우에도 동일하게 적용됩니다 enum.

무엇 짝수 더 위험한를 선언한다

typedef enum bool {
    false, true
} bool;

지금 때문에 모든 값이 1과 0 이외의 무효이고, 이러한 값은 해당 유형의 변수에 할당되어야 동작은 전체적으로 정의되지 않을 것이다 .

따라서 부적합한 변수에 대해 설명 할 수없는 이유로 C99를 사용할 수없는 경우 다음을 사용해야합니다.

  • 입력 int값 0과 1 같은 -입니다 ; 이중 부정을 사용하여 다른 값에서이 값으로 도메인 변환을 신중하게 수행!!
  • 또는 당신이 경우 주장 은 0, falsy 0이 아닌 truish 것을 기억하지 않는 이상 사용에서 대문자 그들이 C99 개념과 혼동되지 않도록하는 것이 : BOOL, TRUE와 FALSE!

1
C 표준의 어떤 부분이 열거 된 유형의 객체가 명시 적으로 나열된 값을 보유하도록 제한합니까? 열거 된 상수의 가장 큰 값이 UCHAR_MAX 또는 USHRT_MAX보다 작은 경우 구현 에서 열거 형보다 작 int거나 유형 unsigned int을 유지할 수 있지만 표준에서 열거 형이 정수 이외의 것으로 작동하는 것을 아는 것은 없습니다. 유형.
— supercat

18
typedef enum {
    false = 0,
    true
} t_bool;

2
2에서 MAX_INT까지도 true로 평가되어야합니다.
— technosaurus

2
@technosaurus! false는 0이 아닌 숫자 일 수 있으므로이 방법을 사용한다고! false == true를 보장하지는 않습니다. 간단한 해결 방법은! false에 true를 명시 적으로 지정하는 것입니다.
— Andrew

3
@Andrew 사실이 아닙니다. !0 = 1C 표준에 의해 그리고 !a = 0임의의 비 - 제로 값 a. 문제는 0이 아닌 모든 것이 참으로 간주된다는 것입니다. 따라서 aand b가 둘 다 "true"인 경우 반드시`a == b` 인 것은 아닙니다.
— Jeremy West

14

C는 부울 타입입니다 : bool (최근 10 (!) 년 동안)

stdbool.h를 포함하면 true / false가 예상대로 작동합니다.


12
표준에서는 10 년이지만 컴파일러에서는 10 년이 아닙니다! MSVC ++의 C 컴파일은 // 주석을 허용하는 것 외에는 C99를 전혀 지원하지 않으며, 그렇게 할 가능성도 없습니다. 또한 _Bool은 C99에서 내장 유형으로 정의되는 반면 bool은 <stdbool.h> 헤더의 typedef입니다.
— Clifford

5
@Clifford 댓글 4 년 후 ... 아무것도 변경되지 않았습니다. MSVC는 C ++ 컴파일러이며 MS가 모든 새로운 C 기능 (C99 및 C11)을 지원하는 데 열중하지 않다고 말한 것으로 생각합니다. 그러나 MSVC가 새로운 C 기능을 이유 (특히 10 년 동안 대답 할 때)로 지원하지 않는다는 사실을 알 수 없습니다 . 프로그래밍 세계에서 10 년은 정말 오랜 시간입니다. 괜찮은 컴파일러라면 벤더가 지원할 계획이라면 10 년 이내에 지원해야합니다.
— PP

2
@ KingsIndian : 왜 당신이 나에게 당신의 의견을 지시했는지 또는 전혀 의견을 말할 필요성을 느꼈습니다. 나는 글을 쓰는 시점에 서서 상황을 말하고 있었다. 나는 그 상황을지지하지 않고 단지 "답변"이 모든 상황에 적용되지 않을 수도 있다고 지적했다.
— Clifford

@Clifford : 엄밀히 말하면 표준은 bool로 확장되는 매크로 여야합니다 _Bool. #undef매크로는 가능하지만 (최소한 과도 측량으로는 허용되지만) untypedeftypedef 는 불가능 하기 때문에 차이점이 중요합니다 . 그러나 첫 번째 의견의 주요 추력은 변경되지 않습니다.
— Jonathan Leffler

2
VS2015 이상 (및 이전의 시점까지)은 C 컴파일 을 bool통한 문제에 아무런 문제가 없습니다 <stdbool.h>. 로 해결됩니다 _Bool.

11

부울 연산에서 0이 아닌 것은 true로 평가되므로

#define TRUE 1
#define FALSE 0

상수를 사용하십시오.


10
그러나 실제 결과는 0이 아닌 값일 수 있으므로 다른 언어와 동등한 if (t == TRUE) {...} 및 if (t) 테스트는 C에서 동일하지 않습니다. .
— Fortega

1
당신 말이 맞지만 C ++에서도 부울 유형이 있습니다. ... 내가 5837834939의 값을 부울 변수를 본 적이 디버깅시
— ggambett을

1
C ++에서 if (t == true) 테스트는 if (t) 테스트와 같습니다. C ++는 일부 변환을 수행하기 때문에 (0이 아니거나 널 포인터 값이 모두 true로 변환 됨)
— Fortega

6
부울 true 값에 대해 가정해야 할 것은 0이 아닌 것입니다. 따라서 if (b)와 같은 코드는 안전하지만 if (b == TRUE)는 안전하지 않습니다. 후자는 나쁜 습관이다.
— Clifford

5

C99를 사용할 수 있다면 다른 답변과 설명을 보완합니다.

+-------+----------------+-------------------------+--------------------+
|  Name | Characteristic | Dependence in stdbool.h |        Value       |
+-------+----------------+-------------------------+--------------------+
| _Bool |   Native type  |    Don't need header    |                    |
+-------+----------------+-------------------------+--------------------+
|  bool |      Macro     |           Yes           | Translate to _Bool |
+-------+----------------+-------------------------+--------------------+
|  true |      Macro     |           Yes           |   Translate to 1   |
+-------+----------------+-------------------------+--------------------+
| false |      Macro     |           Yes           |   Translate to 0   |
+-------+----------------+-------------------------+--------------------+

내 취향 중 일부 :

  • _Bool또는 bool? 둘 다 괜찮지 만 bool키워드보다 좋아 보입니다._Bool .
  • bool및에 허용되는 값 _Bool: false또는 true. 할당 0또는 1대신 false또는 true유효하지만 논리 흐름을 읽고 이해하기가 어렵습니다.

표준의 일부 정보 :

  • _BoolNOT unsigned int은 아니지만 그룹 부호없는 정수 유형의 일부입니다 . 값을 보유 할만큼 크 0거나1 .
  • DO NOT하지만, 그래, 당신은 다시 정의 할 수 있습니다 bool true및false 확인 좋은 생각이 아니다하지만. 이 기능은 폐기 된 것으로 간주되어 향후 제거 될 예정입니다.
  • 할당 스칼라 형 으로 (연산 종류 및 포인터 유형) _Bool또는 bool경우 생성, 스칼라 값과 동일 0또는 비교 0가있을 것 0, 달리 결과는 1: _Bool x = 9; 9으로 변환되는 1지정된 때x .
  • _Bool1 바이트 (8 비트)이며 일반적으로 프로그래머는 다른 비트를 사용하려고 시도하지만 권장되지는 않습니다 char.8 비트가있는 유형 과는 달리 하나의 비트 만 사용하여 데이터를 저장 하는 것입니다. 사용 가능한 비트.

2

이것입니다 :

#define TRUE 1
#define FALSE 0

7
ID는 #define TRUE! FALSE와 같은 것을 사용합니다
— Tom

2

char 또는 다른 작은 숫자 컨테이너를 사용할 수 있습니다.

의사 코드

#define TRUE  1
#define FALSE 0

char bValue = TRUE;

또한 C에서는 일반적으로 int이며 int를 사용하는 다른 코드에 의해 정밀 경고가 손실 될 수 있습니다.
— Thomas Bonini

공간을 수동으로 최적화하지 않는 한 하드웨어의 일반적인 단어 크기 (예 : 일반적으로 int) 를 사용하는 것이 좋습니다 . 일부 아키텍처에서는 이러한 변수에 대한 검사를 풀고 / 마스크해야하므로 성능이 크게 저하되기 때문입니다.
— Kingsley

2

_Bool을 사용할 수 있지만 리턴 값은 정수 여야합니다 (true의 경우 1, false의 경우 0). 말했다 그러나 ++ 포함 및 C로 사용 부울 것을 추천 이 회신 에서 daniweb 포럼 뿐만 아니라, 이 대답 이 다른 유래 질문에서 :

_Bool : C99의 부울 형식입니다. bool, true 또는 false에 대한 매크로를 이미 정의한 레거시 코드를 유지 관리하는 경우에만 _Bool을 직접 사용하는 것이 좋습니다. 그렇지 않으면 해당 매크로가 헤더에서 표준화됩니다. 해당 헤더를 포함하면 C ++에서와 마찬가지로 bool을 사용할 수 있습니다.


2

조건식은 0이 아닌 경우 참으로 간주되지만 C 표준에서는 논리 연산자 자체가 0 또는 1을 반환해야합니다.

@Tom : #define TRUE! FALSE는 나쁘고 완전히 무의미합니다. 헤더 파일이 컴파일 된 C ++ 코드로 들어가면 문제가 발생할 수 있습니다.

void foo(bool flag);

...

int flag = TRUE;
foo(flag);

일부 컴파일러는 int => bool 변환에 대한 경고를 생성합니다. 때때로 사람들은 다음을 수행하여 이것을 피합니다.

foo(flag == TRUE);

식을 C ++ 부울로 만듭니다. 그러나 TRUE! FALSE를 #define하면 다음과 같이 끝납니다.

foo(flag == !0);

어쨌든 경고를 유발할 수있는 int-to-bool 비교를 수행합니다.


1

C99를 사용하는 경우 _Bool유형을 사용할 수 있습니다 . #include필요 하지 않습니다. 여기서 당신은,하지만, 정수처럼 취급해야합니까 1이다 true하고 0있다 false.

그런 다음 TRUE및 을 정의 할 수 있습니다 FALSE.

_Bool this_is_a_Boolean_var = 1;


//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;

또는 당신은 할 수 #include <stdbool.h>및 사용 bool, true그리고 false표준은 당신이 원하는 것처럼.
— SS Anne

1

요즘 C99 는 부울 형식을 지원하지만 필요합니다 #include <stdbool.h>.

예:

#include <stdbool.h>

int main() 
{ 
    bool arr[2] = {true, false}; 

    printf("%d\n", arr[0] && arr[1]);
    printf("%d\n", arr[0] || arr[1]);

    return 0; 
} 

산출:

0
1

0

이것이 내가 사용하는 것입니다 :

enum {false, true};
typedef _Bool bool;

_Bool C에 내장 된 형식입니다. 부울 값을위한 것입니다.


-2

#define다음과 같이 지시문을 간단히 사용할 수 있습니다 .

#define TRUE 1
#define FALSE 0
#define NOT(arg) (arg == TRUE)? FALSE : TRUE
typedef int bool;

다음과 같이 사용하십시오.

bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);

등등


5
NOT 매크로는 괄호로 묶고 arg표현식 전체 를 괄호로 묶어야합니다 #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE). 그러나 거짓 여부를 테스트하는 것이 좋습니다 ( arg0 또는 1 대신 23 인 경우에도 정답을 제공 할 것 #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)입니다.). 그러나 전체 표현 #define NOT(arg) (!(arg))은 물론 같은 결과를 산출 할 수 있습니다.
— Jonathan Leffler
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.