programing

C기준은 true 값을 0 또는 1로 명시하고 있습니까?

prostudy 2022. 7. 6. 20:17
반응형

C기준은 true 값을 0 또는 1로 명시하고 있습니까?

다음 숫자와 같지 않은 숫자는0로 간주되다trueC로 표시되므로 다음과 같이 쓸 수 있습니다.

int a = 16;

while (a--)
    printf("%d\n", a);  // prints numbers from 15 to 0

그러나 true/false는 다음과 같이 정의되는지 궁금했습니다.1/0C로 되어 있기 때문에, 아래의 코드를 시험해 보았습니다.

printf("True = %d, False = %d\n", (0 == 0), (0 != 0));  // prints: True = 1, False = 0

C 표준은 true와 false의 true 값을 다음과 같이 명시적으로 나타냅니까?1그리고.0각각요?

C 표준이 명시적으로 다음 항목의 진실 값을 나타냅니까?true그리고.false~하듯이0그리고.1각각요?

C 표준은 다음을 정의한다.true그리고.false매크로로서stdbool.h로 확장됩니다.1그리고.0각각 다음과 같다.

C11 - 7 7.18 :

나머지 3개의 매크로는 다음에서 사용하기에 적합합니다.#if지시 전처리.그들은 그렇다.

true

정수 상수까지 확장됩니다.1,

false

정수 상수까지 확장됩니다.0[...]

오퍼레이터의 경우==그리고.!=, 표준규격에 따르면

C11 - 6 6 . 5 . 9 / 3 :

==(접수처) 및!=(같지 않은) 연산자는 우선순위가 108)낮다는 점을 제외하고 관계 연산자와 유사합니다.각 측정 시스템의 산출량1지정된 관계가 참이고0틀렸다면.결과에 유형이 있습니다.int모든 오퍼랜드 쌍에 대해 정확히 하나의 관계가 참입니다.

C11에는 명시적으로 표시되어 있지 않습니다.모든 언어 레벨의 연산은 1을 truthy로 반환합니다(NaN을 포함한 0이 아닌 것은 true로 받아들입니다).

  • 에 대해 염려가면_Booltrue는 표준에서는 0과 1만을 유지하도록 요구되기 때문에 true는 1이어야 합니다.(제6.2.5/2)
  • 에도<stdbool.h>매크로true까지 확장하다.1(§7.18/3)
  • ==,!=,<,>,<=그리고.>=0 또는 1을 반환한다(제6.5.8/6, 제6.5.9/3).
  • !,&&그리고.||0 또는 1을 반환한다(제6.5.3.3/5, 제6.5.13/3, 제6.5.14/3)
  • defined0 또는 1로 확장(806.10.1/1)

그러나 모든 표준 라이브러리는 다음과 같이 기능합니다.islowertruthy(예: 77.4.1/1, 177.17.5.1/3, ,7.30.2.1/1, 77.30.2.2.1/4)에 대해 "non zero"라고만 말합니다.


§ 6.2.5/2 : 유형으로 선언된 객체_Bool값은 0과 1을 저장할 수 있을 정도로 큽니다.

§ 6.5.3/5:논리 부정 연산자의 결과!피연산자의 값이 0과 동일하지 않으면 0, 피연산자의 값이 0과 동일하면 1이 됩니다.…

§ 6.5.8/6 : 각 운영자<(미만),>(이보다 작음),<=(이하) 및>=(이하)는 특정 관계가 참일 경우 1, 107) …거짓일 경우 0을 산출한다.

§ 6.5.9/3:==(접수처) 및!=(같지 않은) 연산자는 낮은 우선순위를 제외하고 관계 연산자와 유사합니다.108) 각 연산자는 지정된 관계가 참이면 1이 되고 거짓이면 0이 됩니다.

§ 6.5.13/3: 더&&양쪽 오퍼랜드가 0과 동일하지 않을 경우 오퍼레이터는 1을 산출해야 한다.

§ 6.5.14/3: 더||오퍼랜드 중 하나가 0과 동일하지 않을 경우 오퍼레이터는 1을 산출해야 한다.

§ 6.10.1/1: …양식의 단항 연산자 표현을 포함할 수 있다.defined identifier- 또는 -defined ( identifier )- 이 값은 1로 평가됩니다.

§ 7.4.1 (문자 분류 기능)/1:이 하위 절의 함수는 0이 아닌 경우(true)를 반환합니다.

§ 7.18/3: 나머지 3개의 매크로는 다음 환경에서 사용하기에 적합합니다.#if지시 전처리.그들은...true- 정수 정수 1로 확장됩니다.

§ 7.17.5.1/3:atomic_is_lock_free일반 함수는 개체의 작업이 잠기지 않은 경우에만 0이 아닌 값(true)을 반환합니다.

§ 7.30.2.1 (와이드 문자 분류 기능)/1:이 하위 절의 함수는 0이 아닌 경우(true)를 반환합니다.

§ 7.30.2.2.1/4:iswctype함수는 …의 경우에만 0이 아닌 값(true)을 반환합니다.

제어문, 연산자 및 부울 유형 등 여러 가지가 혼재되어 있습니다.저마다 규칙이 있어요.

control 문은 다음과 같이 동작합니다.ifC11 6.4.8.1:

두 형식 모두 식이 0과 동일하지 않을 경우 첫 번째 서브스테이트먼트가 실행된다.

while,for같은 룰을 가지고 있습니다.이것은 "참"이나 "거짓"과는 아무런 관련이 없습니다.

부울 결과를 산출하는 것으로 추정되는 연산자의 경우, 실제로는int값을 1 또는 0으로 설정합니다.예를 들어 등식 연산자 C11 6.5.9는 다음과 같습니다.

각 연산자는 지정된 관계가 참이면 1, 거짓이면 0을 산출합니다.

위의 모든 것은 1999년까지 C에는 부울 타입이 없었고, 부울 타입을 얻었더라도 위의 규칙은 변경되지 않았기 때문입니다.따라서 문장과 연산자가 (C++ 및 Java와 같은) 부울 타입을 생성하는 대부분의 다른 프로그래밍 언어와는 달리, 이들은 단지 명령어를 생성합니다.int값이 0이거나 0이 아닌 경우.예를들면,sizeof(1==1)C는 4개, C++는 1개입니다.

C의 실제 부울타입에는 이름이 붙습니다._Bool최신 컴파일러가 필요합니다.머리글stdbool.h매크로의 정의bool,true그리고.false로 확장됩니다._Bool,1그리고.0(C++와의 호환성을 위해).


단, 제어문 및 연산자가 실제로 부울 유형을 요구/제공한 것처럼 취급하는 것이 좋은 프로그래밍 관행으로 간주됩니다.MISRA-C와 같은 특정 코딩 표준은 이러한 관행을 권고한다.즉, 다음과 같습니다.

if(ptr == NULL)대신if(ptr).

if((data & mask) != 0)대신if(data & mask).

이러한 스타일의 목적은 정적 분석 도구를 사용하여 유형 안전성을 높이고 버그를 줄이는 것입니다.이 스타일은 정적 분석기를 사용하는 경우에만 의미가 있습니다.경우에 따라서는, 보다 읽기 쉽고, 자기 문서화된 코드로 이어지는 경우도 있습니다.

if(c == '\0') 

좋아, 의도는 분명해 코드는 자체 기록이야

if(c) 

안 좋아. 무슨 의미든 있을 수 있어. 그리고 우린 그 타입의 사람을 찾아야 해.c코드를 이해할 수 있습니다.정수야, 포인터야, 문자야?

Boolean 값을 다룰 때 주의해야 할 표준 영역이 2개 있습니다(특정 C가 아닌 참/거짓 값을 의미합니다).bool/_Bool를 입력합니다.

첫 번째는 표현의 결과와 관련이 있으며 다양한 부분에서 찾을 수 있습니다.C11 6.5 Expressions(예를 들어 관계 연산자 및 등호 연산자).결론은 식에 의해 부울 값이 생성될 때마다 ...라는 것입니다.

...는 지정된 관계가 참일 경우 1, 거짓일 경우 0을 산출합니다.결과는 int 타입입니다.

따라서 부울을 생성하는 식의 결과는 true의 경우 1이 되고 false의 경우 0이 됩니다.이는 에서 찾을 수 있는 내용과 일치합니다.stdbool.h표준 매크로에서true그리고.false같은 방법으로 정의됩니다.

그러나 "보내는 것은 보수적이고 받아들이는 것은 자유롭다"는 강건성 원칙에 따라 부울 컨텍스트에서 정수의 해석이 다소 완화된다는 점에 유의하십시오.

다시 한 번 말씀드리지만6.5다음과 같은 언어가 표시됩니다.

||연산자 중 하나의 피연산자가 0과 동일하지 않을 경우 1을 산출해야 하며 그렇지 않을 경우 0을 산출해야 한다.결과는 int 타입입니다.

이것(및 다른 부분)에서 볼 때, 0은 거짓으로 간주되고 다른 값은 모두 참입니다.


이와는 별도로 부울 생성 및 해석에 사용되는 값을 지정하는 언어는 C99 및 C89에도 나타나기 때문에 오랫동안 존재해 왔습니다.심지어 K&R(ANSI-C 제2판 및 제1판)은 다음과 같은 텍스트 세그먼트와 함께 다음과 같이 명시하였다.

다음과 같은 관계식i > j및 논리 표현은 에 의해 연결되어 있습니다.&&그리고.||가치가 있다고 정의되어 있다.1사실이라면0거짓일 경우.

의 테스트 부분에서if,while,fortrue는 0이 아닌 것을 의미합니다.

&&연산자 ...는 양쪽 오퍼랜드가 0과 동일하지 않으면 1을 반환하고 그렇지 않으면 0을 반환합니다.

||연산자 ...는 피연산자 중 하나가 0과 동일하지 않으면 1을 반환하고 그렇지 않으면 0을 반환합니다.

의 매크로stdbool.hC99에도 표시되지만 그 시점에서는 헤더 파일이 존재하지 않았기 때문에 C89나 K&R에는 표시되지 않습니다.

이 문제는 의 관계 연산자에 의해 발생하였습니다.printf진술.

교환입니다.==및 연산자!=

부터(0 == 0)그것이 사실이고, 그것은 가치를 부여한다.1

반면에.(0 != 0)사실이 아니기 때문에 가치를 부여합니다.0.

나는 여러 언어로 프로그램을 짜왔다.언어에 따라 1 또는 -1이 되는 것을 보았습니다.true가 1인 이면의 논리는 비트가 0 또는 1이라는 것이었습니다.true가 -1이 되는 이면의 논리는 ! 연산자가 하나의 보완자였다는 것입니다.int의 모든 1을 0으로, 모든 0을 1로 변경했습니다.따라서 int의 경우 !0 = -1 및 !(-1) = 0입니다. == true와 비교하지 않고 != false와 비교합니다.그래야 내 프로그래밍 스타일은 모든 언어에서 통한다.그래서 제 대답은 그것에 대해 걱정하지 말고 어느 쪽이든 코드가 올바르게 작동하도록 프로그래밍하는 것입니다.

이 답은 좀 더 자세히 살펴볼 필요가 있다.

C++의 실제 정의는 0이 아닌 것은 모두 true로 처리된다는 것입니다.왜 이것이 관련이 있을까요?C++는 우리가 생각하는 방식으로는 정수가 무엇인지 알 수 없기 때문에 정수가 갖는 의미는 셸과 규칙뿐입니다.단, 비트가 무엇인지, 정수를 구성하는 비트가 무엇인지 알고 있습니다.

정수로서 1은 비트로 느슨하게 표현됩니다.예를 들어 0000 0001로 8비트 부호화된 int를 나타냅니다.우리가 시각적으로 보는 것은 대부분 약간 거짓말이고, -1은 'integer'의 부호 있는 특성 때문에 그것을 표현하는 훨씬 더 일반적인 방법이다. 1은 정말 적절한 것을 의미할 수 없다, 왜일까?왜냐하면 11111110은 운영이 아니기 때문입니다.그것은 부울에 대한 정말 큰 문제입니다.부울에 대해서는 1비트입니다.정말 단순하고 0은 false, 1은 true입니다.모든 논리 연산은 사소한 것으로 간주됩니다.그렇기 때문에 '-1'은 정수(부호 포함)에 대해 'true'로 지정되어야 합니다.111111NOT'ed는 00000000이 됩니다.논리는 유효하고, 우리는 괜찮습니다.부호 없는 ints는 조금 까다롭고 과거에 많이 사용되었습니다.여기서 1은 '0이 아닌 것은 모두 참'이라는 논리를 암시하기 쉽기 때문에 true를 의미합니다.

그게 설명입니다.여기서 인정된 답은 틀렸다고 생각합니다.C/C++의 정의에는 명확한 정의가 없습니다.부울은 부울이므로 정수를 부울로 취급할 수 있지만 출력이 정수라는 사실은 실제로 수행되고 있는 작업에 대해 비트 단위로 알 수 없습니다.

당신 문제에 대한 완벽한 해결책을 찾은 것 같아요.네.0그리고.any non-zero number각각 False와 True입니다.단, C에는 부울 데이터 타입이 없습니다.

하지만 이것은 문제가 아닙니다. 실제 문제는 변수의 수정에 대해 어떻게 대처하느냐입니다.a다음 중 하나를 입력합니다.

int a = 16;

while (a--){
    printf("%d\n", a);
}

컴파일러가 while (condition) 스테이트먼트에 도달했을 때, 첫 번째 값은a컴파일러가 조건을 읽어낸 후 산술 연산이 이루어집니다.이 경우,
a = a - 1 / a -= 1그래서 결국엔...a = 1그리고 산술 연산을 만족시키는 조건입니다.a-- which leads to a = 0, 인쇄 스테이트먼트가 인쇄됩니다.a0 입니다.

위의 시나리오는 다음 명령어를 사용하는지 여부에 따라 달라집니다.--a또는a--이 2개의 스테이트먼트는 컴파일러에 의해 기술된 순서대로 읽힙니다.위해서--a첫 번째로 수술이 행해진다.a그 값은 읽혀지고 다른 값은 반대됩니다.

예를 들면--a언제a = 1먼저 작업이 완료됩니다.a = a - 1 / a -= 1그리고 나서.a상태를 평가하면 Falsy로 판명됩니다.a = 0. 다음 코드를 사용해 보십시오.

int a = 16;

while (--a){
    printf("%d\n", a);   // prints numbers from 15 to 1 as intended
}

또는 의 변경에 대응합니다.awhile 루프 블록 내에 있습니다.

int a = 16;

while(a){
    a = a - 1;           // or a -= 1
    printf("%d\n", a);   // also prints numbers from 15 to 1 as intended
}

언급URL : https://stackoverflow.com/questions/37291681/does-the-c-standard-explicitly-indicate-truth-value-as-0-or-1

반응형