C 표준은 진실 값을 0 또는 1로 명시 적으로 표시합니까?
같지 않은 숫자 는 C 0
로 간주되므로 다음과 같이 true
작성할 수 있습니다.
int a = 16;
while (a--)
printf("%d\n", a); // prints numbers from 15 to 0
그러나, 나는 참 /의 거짓과 같이 정의되어 있는지 궁금했다 1
/ 0
나는 아래의 코드를 시도하므로, C에서 :
printf("True = %d, False = %d\n", (0 == 0), (0 != 0)); // prints: True = 1, False = 0
합니까 C 표준은 명시 적으로 진리의 참 값과 거짓으로 표시 1
하고 0
각각을?
C 표준이 명시 적으로 진리의 값을 표시 하는가
true
와false
같은0
과1
각각을?
는 C 표준을 정의 true
하고 false
같은 매크로에 stdbool.h
되는 확장 1
및 0
각각.
C11-§7.18 :
나머지 세 개의 매크로는
#if
전처리 지시문 에 사용하기에 적합 합니다. 그들은true
이는 정수 상수로 확장
1
,false
정수 상수로 확장되는
0
[...]
운영자 ==
및!=
C11-§6.5.9 / 3 :
는
==
(동일한)와!=
운영자가 자신의 낮은 우선 순위를 제외하고는 관계 연산자와 유사 (안 같음). 108) 각 연산자1
는 지정된 관계가 참이고0
거짓 이면 결과를 산출 합니다 . 결과 유형은int
입니다. 피연산자 쌍의 경우 관계 중 정확히 하나가 참입니다.
C11에는 명시 적으로 표시되어 있지 않습니다. 모든 언어 수준 작업 은 1을 true로 반환하고 NaN을 포함하여 0이 아닌 모든 것을 true로 허용합니다.
- 에 대해 걱정하는 경우
_Bool
표준에서 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 / 3 §6.5.13, §6.5.14 / 3)defined
0 또는 1로 확장 (§6.10.1 / 1)
그러나 모든 표준 라이브러리 함수는 예를 islower
들어 진실을 위해 "0이 아님"이라고 말하면됩니다 (예 : §7.4.1 / 1, §7.17.5.1 / 3, §7.30.2.1 / 1, §7.30.2.2.1 / 4).
§6.2.5 / 2 : 유형
_Bool
으로 선언 된 개체는 값 0과 1을 저장할 수있을만큼 큽니다.§6.5.5.3 / 5 : 논리 부정 연산자의 결과
!
는 피연산자의 값이 0과 같지 않으면 0, 피연산자의 값이 0과 같으면 1입니다.…§6.5.8 / 6 : 각 연산자
<
(보다 작음),>
(보다 큼),<=
(작거나 같음) 및>=
(보다 크거나 같음)은 지정된 관계가 참이면 1을, 그렇지 않으면 0을 산출합니다. 거짓입니다. 107)…§6.5.9 / 3 :
==
(같음) 및!=
(같지 않음) 연산자는 더 낮은 우선 순위를 제외하고 관계 연산자와 유사합니다 .108 ) 지정된 관계가 참이면 각 연산자는 1을, 맞으면 0을 산출합니다. 그릇된. …§6.5.13 / 3 :
&&
연산자는 두 피연산자가 모두 0과 같지 않으면 1을 산출합니다. …§6.5.14 / 3 :
||
연산자는 피연산자 중 하나가 0과 같지 않으면 1을 산출합니다. …§6.10.1 / 1 :… 다음과 같은 경우 1로 평가되는 —
defined identifier
— 또는 —defined ( identifier )
— 형식의 단항 연산자 식을 포함 할 수 있습니다 .§7.4.1 (문자 분류 기능) / 1 :이 하위 절의 기능은 다음과 같은 경우에만 0이 아닌 (참)을 반환합니다.
§7.18 / 3 : 나머지 3 개의 매크로는
#if
전처리 지시문 에 사용하기에 적합 합니다. 그들은 —true
— 정수 상수 1로 확장됩니다.…§7.17.5.1 / 3 :
atomic_is_lock_free
일반 함수는 객체의 작업이 잠금이없는 경우에만 0이 아닌 (true)을 반환합니다. …§7.30.2.1 (와이드 문자 분류 기능) / 1 :이 하위 절의 기능은 다음과 같은 경우에만 0이 아닌 (참)을 반환합니다.
§7.30.2.2.1 / 4 : 다음
iswctype
과 같은 경우에만 0이 아닌 값 (true)을 반환합니다.
C에서 부울 값 (특정 C bool/_Bool
유형이 아닌 참 / 거짓 값을 의미 함)을 다룰 때 알아야 할 두 가지 표준 영역이 있습니다 .
첫 번째는 표현식 의 결과 와 관련이 있으며의 다양한 부분에서 찾을 수 있습니다 C11 6.5 Expressions
(예 : 관계형 및 같음 연산자). 결론은 표현식에 의해 부울 값이 생성 될 때마다 ...
... 지정된 관계가 참이면 1을, 거짓이면 0을 산출합니다. 결과는 int 유형입니다.
So, yes, the result of any Boolean-generating expression will be one for true, or zero for false. This matches what you will find in stdbool.h
where the standard macros true
and false
are defined the same way.
Keep in mind however that, following the robustness principle of "be conservative in what you send, liberal in what you accept", the interpretation of integers in the Boolean context is somewhat more relaxed.
Again, from various parts of 6.5
, you'll see language like:
The
||
operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.
From that (and other parts), it's obvious that zero is considered false and any other value is true.
As an aside, the language specifying what value are used for Boolean generation and interpretation also appear back in C99 and C89 so they've been around for quite some time. Even K&R (ANSI-C second edition and the first edition) specified that, with text segments such as:
Relational expressions like
i > j
and logical expressions connected by&&
and||
are defined to have value1
if true, and0
if false.In the test part of
if
,while
,for
, etc, "true" just means "non-zero".The
&&
operator ... returns 1 if both its operands compare unequal to zero, 0 otherwise.The
||
operator ... returns 1 if either its operands compare unequal to zero, and 0 otherwise.
The macros in stdbool.h
appear back in C99 as well, but not in C89 or K&R since that header file did not exist at that point.
You are mixing up a lot of different things: control statements, operators and boolean types. Each have their own rules.
Control statements work like for example the if
statement, C11 6.4.8.1:
In both forms, the first substatement is executed if the expression compares unequal to 0.
while
, for
etc have the same rule. This has nothing to do with "true" or "false".
As for operators that are supposedly yielding a boolean result, they are actually yielding an int
with value 1 or 0. For example the equality operators, C11 6.5.9:
Each of the operators yields 1 if the specified relation is true and 0 if it is false
All of the above is because C did not have a boolean type until the year 1999, and even when it did get one, the above rules weren't changed. So unlike most other programming languages where statements and operators yield a boolean type (like C++ and Java), they just yield an int
, with a value zero or not zero. For example, sizeof(1==1)
will give 4 in C but 1 in C++.
The actual boolean type in C is named _Bool
and requires a modern compiler. The header stdbool.h
defines macros bool
, true
and false
, that expand to _Bool
, 1
and 0
respectively (for compatibility with C++).
It is however considered good programming practice to treat control statements and operators as if they actually required/yielded a boolean type. Certain coding standards like MISRA-C recommend such practice. That is:
if(ptr == NULL)
instead of if(ptr)
.
if((data & mask) != 0)
instead of if(data & mask)
.
The aim of such style is to increase type safety with the aid of static analysis tools, which in turn reduces bugs. Arguably, this style is only meaningful if you do use static analysers. Though in some cases it leads to more readable, self-documenting code, for example
if(c == '\0')
Good, the intent is clear, the code is self-documenting.
versus
if(c)
Bad. Could mean anything, and we have to go look for the type of c
to understand the code. Is it an integer, a pointer or a character?
I've programmed in many languages. I've seen true be 1 or -1 depending on the language. The logic behind true being 1 was that a bit was either a 0 or 1. The logic behind true being -1 was that the ! operator was a one's complement. It changed all the 1's to 0's and all the 0's to 1's in an int. So, for an int, !0 = -1 and !(-1) = 0. This has tripped me up enough that I don't compare something to be == true, but instead compare it to be != false. That way, my programming style works in every language. So my answer is to not worry about it, but program so that your code works correctly either way.
This answer needs to be looked at a bit more closely.
The actual definition in C++ is that anything not 0 is treated as true. Why is this relevant? Because C++ doesn't know what an integer is by how we think about it--we create that meaning, all it holds is the shell and rules for what that means. It knows what bits are though, that which make up an integer.
1 as an integer is loosely represented in bits, say an 8-bit signed int as 0000 0001. Many times what we see visually is a bit of a lie, -1 is a much more common way to represent it because of the signed nature of 'integer'. 1 really can't mean true proper, why? Because it's NOT operation is 1111 1110. That's a really major issue for a boolean. When we talk about a boolean, it's just 1 bit--it's really simple, 0 is false and 1 is true. All the logic operations hold as trivial. This is why '-1' should be designated as 'true' for integers (signed). 1111 1111 NOT'ed becomes 0000 0000---the logic holds and we're good. Unsigned ints is a little bit tricky and were a lot more commonly used in the past--where 1 means true because it's easy to imply the logic that 'anything not 0 is true'.
That's the explanation. I say the accepted answer here is wrong--there is no clear definition in the C/C++ definition. A boolean is a boolean, you can treat an integer as a boolean, but the fact the output is an integer says nothing about the operation actually being done is bitwise.
It happened because of the Relational Operators in your printf
statement.
Operator ==
and operator !=
Since (0 == 0)
holds true so, it gives a value 1
whereas, (0 != 0)
doesn't hold true so, gives a value 0
.
'developer tip' 카테고리의 다른 글
nodejs 원시 버퍼 데이터를 16 진수 문자열로 표시하는 방법 (0) | 2020.09.24 |
---|---|
기본값없이 사용자 프로필에 nullable이 아닌 필드 'new_field'를 추가하려고합니다. (0) | 2020.09.24 |
Karma-Jasmine 단위 테스트 사례를 작성하는 동안 "오류 : 라우터에 대한 공급자 없음" (0) | 2020.09.24 |
내 애플리케이션의 설정 번들에 애플리케이션 버전 개정을 표시하려면 어떻게해야합니까? (0) | 2020.09.23 |
JavaFX : 초기화 중에 컨트롤러에서 스테이지를 가져 오는 방법은 무엇입니까? (0) | 2020.09.23 |