C에는 내장 된 부울 유형이 없습니다. C에서 사용하는 가장 좋은 방법은 무엇입니까?
C에는 내장 된 부울 유형이 없습니다. C에서 사용하는 가장 좋은 방법은 무엇입니까?
답변:
최선에서 최악으로 :
옵션 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 번으로 가십시오!
<stdbool.h>
bool
컴파일러가 선택한 정렬, 최적화 및 저장 방법 은 부울 값의 의도 된 목적에보다 적합 할 수 있습니다 int
(즉, 컴파일러 는와 bool
다르게 구현하도록 선택할 수 있음 int
). 운이 좋으면 컴파일 타임에 엄격한 유형 검사가 발생할 수도 있습니다.
int
을위한 bool
? 낭비입니다. 사용하십시오 unsigned char
. 또는 C의 builtin을 사용하십시오 _Bool
.
C의 부울에 대한 몇 가지 생각 :
나는 int
typedef 또는 특별한 정의 또는 참 / 거짓 값에 대한 열거없이 평범한 부울 유형으로 일반을 사용하기에 충분히 나이가 들었습니다. 부울 상수와 비교하지 않는 아래의 제안을 따르는 경우 어쨌든 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
.
a == b
작동 하지 않습니까?
a
하고 b
0부터 카운트, 내가 권하고 싶습니다 a > 0 == b > 0
대신. 0이 아닌 임의의 값의 진실성을 이용한다고 주장하면와 !!var
같은 부울 0/1 값을 생성 var
하므로 글을 쓸 수 !!a == !!b
는 있지만 독자는 다소 혼란 스럽습니다.
!a == !b
또한 동등성을 테스트하기에 충분하며, 0이 아닌 값은 0이되고 0은 1이됩니다.
!!a
"부울이 아닌 값을 동등한 값 !a
으로 변환"으로 읽는 반면 "부울 변수 a를 논리적으로 반전"으로 읽는 것 같습니다 . 특히 논리적 반전이 필요한 특정 이유를 찾고 싶습니다.
내가 사용한 버전은 다음과 같습니다.
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,
true
, false
및 bool
강조 표시됩니다 대부분의 IDE의 그들은 반대로 열거 값과 타입 정의, 때문에 #defines
거의 이제까지 구문 강조 표시됩니다.
gcc -ansi -pedantic -Wall
는 경고를 제공하지 않으므로 신뢰합니다 gcc
. 이것이 효과가 있다면 c89
잘 작동합니다 c99
.
!
단지 값을 반환 할 수 있습니다 0
및 1
그래서 true = !false
항상 할당 값 1이 방법은 여분의 안전을 이상 제공하지 않습니다 것입니다 typedef enum { false, true } bool;
.
if(!value)
)에 중요하지 않은 경우이 규칙을 법적으로 무시할 수 있지만이 경우에는 예외가 적용되지 않습니다.
C99 컴파일러를 사용하는 경우 bool 유형을 기본적으로 지원합니다.
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
먼저 첫 번째 것들. 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
- 스칼라 값이로 변환 될 때 값이
_Bool
0과 비교되면 결과는 0입니다. 그렇지 않으면 결과는 1입니다. 59)각주
59) NaN은 0과 같지 않으므로 1로 변환됩니다.
으로 typedef
장소에서의이 double
강제 변환 될 수 int
의 두 배의 값이 범위 내에없는 경우는 - int
1, 행동이 정의되어 있지 않습니다 .
if true
및 false
에 선언 된 경우에도 동일하게 적용됩니다 enum
.
무엇 짝수 더 위험한를 선언한다
typedef enum bool {
false, true
} bool;
지금 때문에 모든 값이 1과 0 이외의 무효이고, 이러한 값은 해당 유형의 변수에 할당되어야 동작은 전체적으로 정의되지 않을 것이다 .
따라서 부적합한 변수에 대해 설명 할 수없는 이유로 C99를 사용할 수없는 경우 다음을 사용해야합니다.
int
값 0
과 1
같은 -입니다 ; 이중 부정을 사용하여 다른 값에서이 값으로 도메인 변환을 신중하게 수행!!
BOOL
, TRUE
와 FALSE
!int
거나 유형 unsigned int
을 유지할 수 있지만 표준에서 열거 형이 정수 이외의 것으로 작동하는 것을 아는 것은 없습니다. 유형.
typedef enum {
false = 0,
true
} t_bool;
!0 = 1
C 표준에 의해 그리고 !a = 0
임의의 비 - 제로 값 a
. 문제는 0이 아닌 모든 것이 참으로 간주된다는 것입니다. 따라서 a
and b
가 둘 다 "true"인 경우 반드시`a == b` 인 것은 아닙니다.
C는 부울 타입입니다 : bool (최근 10 (!) 년 동안)
stdbool.h를 포함하면 true / false가 예상대로 작동합니다.
bool
로 확장되는 매크로 여야합니다 _Bool
. #undef
매크로는 가능하지만 (최소한 과도 측량으로는 허용되지만) untypedef
typedef 는 불가능 하기 때문에 차이점이 중요합니다 . 그러나 첫 번째 의견의 주요 추력은 변경되지 않습니다.
부울 연산에서 0이 아닌 것은 true로 평가되므로
#define TRUE 1
#define FALSE 0
상수를 사용하십시오.
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
유효하지만 논리 흐름을 읽고 이해하기가 어렵습니다.표준의 일부 정보 :
_Bool
NOT unsigned int
은 아니지만 그룹 부호없는 정수 유형의 일부입니다 . 값을 보유 할만큼 크 0
거나1
.bool
true
및false
확인 좋은 생각이 아니다하지만. 이 기능은 폐기 된 것으로 간주되어 향후 제거 될 예정입니다._Bool
또는 bool
경우 생성, 스칼라 값과 동일 0
또는 비교 0
가있을 것 0
, 달리 결과는 1
: _Bool x = 9;
9
으로 변환되는 1
지정된 때x
._Bool
1 바이트 (8 비트)이며 일반적으로 프로그래머는 다른 비트를 사용하려고 시도하지만 권장되지는 않습니다 char
.8 비트가있는 유형 과는 달리 하나의 비트 만 사용하여 데이터를 저장 하는 것입니다. 사용 가능한 비트.char 또는 다른 작은 숫자 컨테이너를 사용할 수 있습니다.
의사 코드
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
int
) 를 사용하는 것이 좋습니다 . 일부 아키텍처에서는 이러한 변수에 대한 검사를 풀고 / 마스크해야하므로 성능이 크게 저하되기 때문입니다.
_Bool을 사용할 수 있지만 리턴 값은 정수 여야합니다 (true의 경우 1, false의 경우 0). 말했다 그러나 ++ 포함 및 C로 사용 부울 것을 추천 이 회신 에서 daniweb 포럼 뿐만 아니라, 이 대답 이 다른 유래 질문에서 :
_Bool : C99의 부울 형식입니다. bool, true 또는 false에 대한 매크로를 이미 정의한 레거시 코드를 유지 관리하는 경우에만 _Bool을 직접 사용하는 것이 좋습니다. 그렇지 않으면 해당 매크로가 헤더에서 표준화됩니다. 해당 헤더를 포함하면 C ++에서와 마찬가지로 bool을 사용할 수 있습니다.
조건식은 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 비교를 수행합니다.
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
표준은 당신이 원하는 것처럼.
#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);
등등
arg
표현식 전체 를 괄호로 묶어야합니다 #define NOT(arg) (((arg) == TRUE) ? FALSE : TRUE)
. 그러나 거짓 여부를 테스트하는 것이 좋습니다 ( arg
0 또는 1 대신 23 인 경우에도 정답을 제공 할 것 #define NOT(arg) (((arg) == FALSE) ? TRUE : FALSE)
입니다.). 그러나 전체 표현 #define NOT(arg) (!(arg))
은 물론 같은 결과를 산출 할 수 있습니다.