답변:
이 방법은 실제 사용 boolean
(과 해결 유형 true
및 false
컴파일러가 지원하는 경우). (특히 C ++)
그러나, C는 ++합니다 (통해 사용 여부를 확인하는 것이 좋습니다 것 __cplusplus
매크로) 실제로 사용 true
하고 false
.
C 컴파일러에서 이것은 0
and와 동일합니다 1
.
(괄호를 제거하면 작업 순서로 인해 중단됩니다.)
boolean
유형이 있습니까?
true
나 false
.
#define TRUE true
및 #define FALSE false
때마다를 __cplusplus
정의한다.
대답은 이식성입니다. 의 숫자 값 TRUE
과는 FALSE
중요하지 않습니다. 무엇 입니다 중요한 것은 같은 문이 if (1 < 2)
평가 if (TRUE)
와 같은 문 if (1 > 2)
으로 평가 if (FALSE)
.
C에서, 부여, (1 < 2)
평가됩니다에 1
와 (1 > 2)
평가됩니다에 0
다른 사람이 말했듯이, 그래서, 컴파일러에 관한 한 지금까지 한 실제적인 차이가 없습니다. 그러나 컴파일러 가 자체 규칙에 따라 정의 TRUE
하고 정의하게함으로써 FALSE
프로그래머에게 그 의미를 명확하게 표시 할 수 있으며 프로그램과 다른 라이브러리 내에서 일관성을 보장 할 수 있습니다 (다른 라이브러리가 C 표준을 따르는 것으로 가정하면 ... 놀랐습니다).
일부 역사
몇 가지 기본 정의 FALSE
로 0
와 TRUE
같은 -1
. 많은 현대 언어와 마찬가지로, 그들은 0이 아닌 모든 값을로 해석TRUE
했지만로 부울 표현식을 평가 했습니다 -1
. 그들의 NOT
작업은 1을 추가하고 부호를 뒤집어서 구현되었습니다. 그렇게하는 것이 효율적이기 때문입니다. 그래서 'NOT x'가되었습니다 -(x+1)
. 이것의 부작용은와 같은 값은로 5
평가 TRUE
하지만로 NOT 5
평가한다는 -6
것입니다 TRUE
. 이런 종류의 버그를 찾는 것은 재미 있지 않습니다.
모범 사례는
주어진 사실상 제로로 해석 것을 규정 FALSE
하고 있는 것처럼 아닌 값이 해석됩니다 TRUE
당신이해야 에 부울 보이는 표현을 비교 결코 TRUE
또는FALSE
. 예 :
if (thisValue == FALSE) // Don't do this!
if (thatValue == TRUE) // Or this!
if (otherValue != TRUE) // Whatever you do, don't do this!
왜? 많은 프로그래머들이 int
s를 bool
s 로 취급하는 지름길을 사용하기 때문에 . 그것들은 동일하지 않지만 컴파일러는 일반적으로 그것을 허용합니다. 예를 들어 글을 쓰는 것은 합법적입니다
if (strcmp(yourString, myString) == TRUE) // Wrong!!!
그것은 합법적으로 보이며 컴파일러는 행복하게 받아 들일 것입니다. 그러나 아마도 원하는 것을하지 않을 것입니다. 의 반환 값 strcmp()
이
만약 0 yourString == myString
<0 인 경우 yourString < myString
> 0 인 경우yourString > myString
따라서 위의 줄은 TRUE
when 만 반환 합니다 yourString > myString
.
이 작업을 수행하는 올바른 방법은
// Valid, but still treats int as bool.
if (strcmp(yourString, myString))
또는
// Better: lingustically clear, compiler will optimize.
if (strcmp(yourString, myString) != 0)
비슷하게:
if (someBoolValue == FALSE) // Redundant.
if (!someBoolValue) // Better.
return (x > 0) ? TRUE : FALSE; // You're fired.
return (x > 0); // Simpler, clearer, correct.
if (ptr == NULL) // Perfect: compares pointers.
if (!ptr) // Sleazy, but short and valid.
if (ptr == FALSE) // Whatisthisidonteven.
프로덕션 코드에서 이러한 "나쁜 예"중 일부를 발견 할 수 있으며 숙련 된 프로그래머가 맹세합니다. 제대로 작동하고 일부는 (대체적으로?) 올바른 대안보다 짧으며 관용구는 거의 보편적으로 인식됩니다. 그러나 "올바른"버전은 효율성이 떨어지지 않으며 이식성이 보장되며 가장 엄격한 정보도 전달할 수 있으며 심지어 새로운 프로그래머도 이해할 수 있습니다.
그만한 가치가 없습니까?
(1==1)
보다 더 이식성이 없습니다 1
. 컴파일러 자체의 규칙은 C 언어의 규칙으로, 평등 및 관계 연산자의 의미에 대해 명확하고 모호하지 않습니다. 컴파일러 가이 물건을 잘못 본 것을 본 적이 없습니다.
strcmp
은 0보다 작거나 같거나 0보다 큰 것으로 알려져 있습니다. -1, 0 또는 1을 보장하지는 않으며 구현 속도를 얻기 위해 해당 값을 반환하지 않는 플랫폼이 있습니다. 그렇다면 strcmp(a, b) == TRUE
다음 a > b
그러나 반대 의미는 개최하지 않을 수 있습니다.
(1==1)
및 1
타입 모두 일정한 표현이다 int
그들은 동일한 의미 값 1로. 나는 그것을 모르는 독자들에게 제공하는 코드를 작성할 수 있다고 생각하지만 어디에서 끝나는가?
이 (1 == 1)
트릭은 TRUE
C에 투명한 방식으로 정의하는 데 유용 하지만 C ++에서 더 나은 타이핑을 제공합니다. "Clean C"(C 또는 C ++로 컴파일 됨)라는 방언으로 작성하거나 C 또는 C ++ 프로그래머가 사용할 수있는 API 헤더 파일을 작성하는 경우 동일한 코드를 C 또는 C ++로 해석 할 수 있습니다.
C 변환 단위에서 ; 1 == 1
과 정확히 동일한 의미를 갖습니다 1
. 와 1 == 0
같은 의미 0
입니다. 그러나 C ++ 변환 단위에서 1 == 1
유형은 bool
입니다. 따라서 TRUE
매크로는 그런 식으로 C ++에 더 잘 통합됩니다.
더 나은 통합하는 방법의 예는 예를 들어 기능이있는 경우이다 foo
에 대한 과부하가 int
와에 대한 bool
다음, foo(TRUE)
선택합니다 bool
과부하를. TRUE
방금 정의 된 경우 1
C ++에서 제대로 작동하지 않습니다. 과부하 foo(TRUE)
를 원할 int
것입니다.
물론, C99 도입 bool
, true
및 false
이들은 헤더 파일에서 사용할 수있는 C99와 C.와 작업이
하나:
TRUE
과 FALSE
같은 (0==0)
및 (1==0)
C99 선행한다.당신이 혼합 C 및 C ++ 프로젝트에 노력하고 있으며, C99을 원하지 않는 경우, 소문자를 정의 true
, false
그리고 bool
대신.
#ifndef __cplusplus
typedef int bool;
#define true (0==0)
#define false (!true)
#endif
즉, 0==0
일부 프로그래머는 어떤 식 으로든 C ++과 상호 운용되지 않는 코드조차도 트릭을 사용했습니다. 그것은 아무것도 사지 않으며 프로그래머가 C에서 부울이 어떻게 작동하는지 오해하고 있음을 시사합니다.
C ++ 설명이 명확하지 않은 경우 테스트 프로그램이 있습니다.
#include <cstdio>
void foo(bool x)
{
std::puts("bool");
}
void foo(int x)
{
std::puts("int");
}
int main()
{
foo(1 == 1);
foo(1);
return 0;
}
출력 :
bool
int
오버로드 된 C ++ 함수가 혼합 C 및 C ++ 프로그래밍과 어떻게 관련되어 있는지에 대한 의견에서 의문을 제기합니다. 이들은 단지 유형 차이를 보여줍니다. C ++로 컴파일 true
할 bool
때 상수를 유지 해야하는 유효한 이유는 완전한 진단입니다. 가장 높은 경고 수준에서 C ++ 컴파일러는 정수를 bool
매개 변수 로 전달하면 변환에 대해 경고 할 수 있습니다 . Clean C로 작성하는 한 가지 이유는 코드가 이식성이 높을뿐 아니라 (C 컴파일러뿐만 아니라 C ++ 컴파일러도 이해할 수 있기 때문에) C ++ 컴파일러의 진단 의견을 활용할 수 있기 때문입니다.
TRUE
C ++ 에서 두 가지 정의 가 다르다는 것은 전혀 분명하지 않습니다 .
#ifdef __cplusplus
의도를 훨씬 더 명확하게 표현 하는 데 사용할 수 있습니다 .
bool
와 int
실제로 중요하지 않습니다. 실제로 "동일한" , 따옴표를주의 )하지만 실제로 두 가지 사이에서 매복 해야 할 상황이 많지 않습니다 . " 템플릿을 사용하는 코드와 오버로드하는 것보다 훨씬 적을 것 " 은 아마도 " 너무 많지" 않았을 것입니다.
#define TRUE (1==1)
#define FALSE (!TRUE)
에 해당
#define TRUE 1
#define FALSE 0
C.에서
관계 연산자의 결과는 0
또는 1
입니다. 1==1
로 평가 될 보장 1
과 !(1==1)
로 평가 될 보장됩니다 0
.
첫 번째 양식을 사용해야 할 이유는 없습니다. 그러나 첫 번째 형식은 거의 모든 컴파일러에서 상수 표현식이 런타임이 아닌 컴파일 타임에 평가되므로 덜 효율적이지 않습니다. 이 규칙에 따라 허용됩니다.
(C99, 6.6p2) "상수 표현식은 런타임이 아닌 변환 중에 평가할 수 있으므로 상수가있는 곳이면 어디에서나 사용할 수 있습니다."
TRUE
및 FALSE
매크로에 리터럴을 사용하지 않으면 PC-Lint에서 메시지 (506, 상수 값 부울)를 발행 합니다.
C의 경우
TRUE
로 정의해야합니다1
. 그러나 다른 언어는 1 이외의 양을 사용하므로 일부 프로그래머!0
는 안전하게 재생한다고 생각합니다.
또한 C99에서 stdbool.h
부울 매크로에 대한 정의 true
및 false
직접 리터럴을 사용합니다 :
#define true 1
#define false 0
1==1
로 평가 될 보장1
if(foo == true)
, 이는 나쁜 습관에서 플랫 버그로 바뀔 것입니다.
(x == TRUE)
다른 진리 값을 가질 수 있습니다 x
.
C ++ (이미 언급 했음) 외에도 정적 분석 도구가 또 다른 이점입니다. 컴파일러는 비 효율성을 제거하지만 정적 분석기는 자체 추상 유형을 사용하여 비교 결과와 다른 정수 유형을 구별 할 수 있으므로 TRUE는 비교의 결과 여야하며 호환되지 않아야한다는 것을 암시 적으로 알고 있습니다. 정수로.
물론 C는이 호환되는지 말한다,하지만 당신은 도움이 강조 버그에 해당 기능의 의도적 인 사용을 금지하도록 선택할 수 있습니다 - 예를 들어, 누군가가 혼동이있을 수 있습니다 경우 &
와 &&
, 또는 그들의 연산자 우선 순위를 실수 한 것.
if (boolean_var == TRUE)
에 확장을 통해 바보 같은 코드 를 포착 할 수도 있습니다 . if (boolean_var == (1 == 1))
(1 == 1)
if (<*> == <boolean_expr>)
실질적인 차이는 없습니다. 0
로 평가 false
되고 1
로 평가됩니다 true
. 당신이 사용하는 것이 사실 부울 식을 ( 1 == 1
) 또는 1
정의는 true
, 어떤 차이가되지 않습니다. 그들은 둘 다 평가int
.
C 표준 라이브러리는 부울 정의를위한 특정 헤더를 제공합니다 stdbool.h
.
true
로 평가 1
되고 false
로 평가됩니다 0
. C는 네이티브 부울 유형에 대해 알지 못하며 정수입니다.
int
는 값이 0
또는 형식 인 유형의 결과를 생성합니다 1
. C에는 실제 부울 유형 ( _Bool
,에 bool
정의 된 매크로가 <stdbool.h>
있지만 C99에만 추가되었으므로 새 유형을 사용하도록 연산자의 의미를 변경 하지 않았습니다)
_Bool
하고 <stdbool.h>
있습니다 #define bool _Bool
.
1 == 1
로 평가되는 것에 대해 옳습니다 int
. 편집했습니다.
우리는 TRUE가 정확한 정확한 값을 알지 못하며 컴파일러는 자체 정의를 가질 수 있습니다. 그래서 당신이 권한을 부여하는 것은 정의를 위해 컴파일러의 내부 컴파일러를 사용하는 것입니다. 프로그래밍 습관이 좋은 경우에는 항상 필요한 것은 아니지만 코딩 스타일이 좋지 않은 경우 문제를 피할 수 있습니다.
if ((a> b) == 참)
TRUE를 수동으로 1로 정의하면 TRUE의 내부 값이 또 다른 값이됩니다.
>
연산자는 항상 1이면 true, 0이면 false입니다. C 컴파일러가 이것을 잘못받을 가능성은 없습니다. 평등 한 스타일 TRUE
과 FALSE
스타일의 평등 한 비교 ; 위의 내용은보다 명확하게 씁니다 if (a > b)
. 그러나 다른 C 컴파일러가 진실과 거짓을 다르게 취급 할 수 있다는 생각은 잘못되었습니다.
일반적으로 C 프로그래밍 언어에서 1은 true로 정의되고 0은 false로 정의됩니다. 따라서 다음을 자주 보는 이유는 무엇입니까?
#define TRUE 1
#define FALSE 0
그러나 조건문에서 0이 아닌 숫자는 true로 평가됩니다. 따라서 아래를 사용하여
#define TRUE (1==1)
#define FALSE (!TRUE)
사실이 아닌 것과 거짓을 동일하게하여 안전하게 플레이하려고한다는 것을 명시 적으로 보여줄 수 있습니다.
#define TRUE (’/’/’/’)
;#define FALSE (’-’-’-’)
( coding-guidelines.com/cbook/cbook1_1.pdf 871 페이지 에서 가져옴 )