C에서 정의를 보았습니다.
#define TRUE (1==1)
#define FALSE (!TRUE)
이것이 필요합니까? 단순히 TRUE를 1로 정의하고 FALSE를 0으로 정의하면 어떤 이점이 있습니까?
답변
이 방법은 실제 사용 boolean
(과 해결 유형 true
및 false
컴파일러가 지원하는 경우). (특히 C ++)
그러나, C는 ++합니다 (통해 사용 여부를 확인하는 것이 좋습니다 것 __cplusplus
매크로) 실제로 사용 true
하고 false
.
C 컴파일러에서 이것은 0
and와 동일합니다 1
.
(괄호를 제거하면 작업 순서로 인해 중단됩니다.)
답변
대답은 이식성입니다. 의 숫자 값 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)
트릭은 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 선행한다. - C99를 멀리하고 C90과 함께 작업해야 할 이유는 여전히 있습니다.
당신이 혼합 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 ++ 컴파일러의 진단 의견을 활용할 수 있기 때문입니다.
답변
#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
답변
C ++ (이미 언급 했음) 외에도 정적 분석 도구가 또 다른 이점입니다. 컴파일러는 비 효율성을 제거하지만 정적 분석기는 자체 추상 유형을 사용하여 비교 결과와 다른 정수 유형을 구별 할 수 있으므로 TRUE는 비교의 결과 여야하며 호환되지 않아야한다는 것을 암시 적으로 알고 있습니다. 정수로.
물론 C는이 호환되는지 말한다,하지만 당신은 도움이 강조 버그에 해당 기능의 의도적 인 사용을 금지하도록 선택할 수 있습니다 – 예를 들어, 누군가가 혼동이있을 수 있습니다 경우 &
와 &&
, 또는 그들의 연산자 우선 순위를 실수 한 것.
답변
실질적인 차이는 없습니다. 0
로 평가 false
되고 1
로 평가됩니다 true
. 당신이 사용하는 것이 사실 부울 식을 ( 1 == 1
) 또는 1
정의는 true
, 어떤 차이가되지 않습니다. 그들은 둘 다 평가int
.
C 표준 라이브러리는 부울 정의를위한 특정 헤더를 제공합니다 stdbool.h
.
답변
우리는 TRUE가 정확한 정확한 값을 알지 못하며 컴파일러는 자체 정의를 가질 수 있습니다. 그래서 당신이 권한을 부여하는 것은 정의를 위해 컴파일러의 내부 컴파일러를 사용하는 것입니다. 프로그래밍 습관이 좋은 경우에는 항상 필요한 것은 아니지만 코딩 스타일이 좋지 않은 경우 문제를 피할 수 있습니다.
if ((a> b) == 참)
TRUE를 수동으로 1로 정의하면 TRUE의 내부 값이 또 다른 값이됩니다.