할당과 평등 검사를 결합한 if 문이 왜 true를 반환합니까?
나는 초보자 실수를 생각하고 있었고 if
성명서 에서 실수로 끝났습니다 . 코드를 조금 확장했습니다.
int i = 0;
if (i = 1 && i == 0) {
std::cout << i;
}
나는이 본 if
문 반환 사실, 그것은 cout
의 i
로 1
. 경우 i
할당 1
한 이유는 if 문에서 i == 0
수익을 true
?
이것은 연산자 우선 순위 와 관련이 있습니다 .
if (i = 1 && i == 0)
아니다
if ((i = 1) && (i == 0))
모두 있기 때문에 &&
그리고 ==
보다 높은 우선 순위를 가지고 =
. 그것이 실제로 작동하는 것은
if (i = (1 && (i == 0)))
이는 할당의 결과 1 && (i == 0)
로이 i
. 그래서, 만약 i
에 시작 0
후이 i == 0
있다 true
, 그래서 1 && true
이다 true
(또는 1
), 다음 i
으로 설정됩니다 1
. 그런 다음 1
true이므로 if 블록을 입력하고에 할당 한 값을 인쇄하십시오 i
.
코드가 실제로 다음과 같다고 가정합니다.
#include <iostream>
using namespace std;
int main() {
int i = 0;
if (i = 1 && i == 0) {
cout << i;
}
}
그런 다음 :
if (i = 1 && i == 0) {
로 평가
if (i = (1 && i == 0)) {
등 i
으로 설정되어 있습니다 1
.
실제 답변은 다음과 같습니다.
- 컴파일러는 "i == 0"에 우선 순위 를 부여 하며, 이는 true로 평가됩니다.
- 그런 다음 i = 1을 TRUE 또는 FALSE로 평가하고 컴파일 된 할당 연산자가 실패하지 않기 때문에 (그렇지 않으면 컴파일하지 않음) true로 평가됩니다.
- 두 명령문이 모두 true로 평가되고 TRUE && TRUE는 TRUE로 평가되므로 if 문은 TRUE로 평가됩니다.
증거로, 입력 한 코드에 대한 컴파일러의 asm 출력을 살펴보십시오 (모든 주석은 내 자신의 것입니다).
mov dword ptr [rbp - 8], 0 ; i = 0;
cmp dword ptr [rbp - 8], 0 ; i == 0?
sete al ; TRUE (=1)
mov cl, al
and cl, 1 ; = operator always TRUE
movzx edx, cl
mov dword ptr [rbp - 8], edx ; set i=TRUE;
test al, 1 ; al never changed,
; so final ans is TRUE
위의 asm 출력은 CLANG에서 가져온 것이지만 내가 본 다른 모든 컴파일러는 비슷한 출력을 냈습니다. 이는 해당 사이트의 모든 컴파일러가 순수 C 또는 C ++ 컴파일러인지 여부에 관계없이 컴파일러 모드를 변경하는 데 아무런 관용구가없는 것입니다 (기본적으로 C ++ 컴파일러의 경우 C ++ 임)
Note that your compiler did not actually set i=1, but i=TRUE (which means any 32-bit not zero integer value). That's because the && operator only evaluates whether a statement is TRUE or FALSE, and then sets the results according to that result. As proof, try changing i=1 to i=2 and you can observe for yourself that nothing will change. See for yourself using any online compiler at Compiler Explorer
It has to do with parsing an the right to left rules. Eg y = x+5.
All sub-expressions are weighted in importance. Two expressions of equal importance are evaluated right to left, . The && expression side is done first, followed by the LHS.
Makes sense to me.
'IT story' 카테고리의 다른 글
파이썬에서 Xpath를 사용하는 방법? (0) | 2020.04.28 |
---|---|
Java 어노테이션 멤버에 어떤 유형을 사용할 수 있습니까? (0) | 2020.04.28 |
루비에서 낙타 케이스를 밑줄 케이스로 변환 (0) | 2020.04.26 |
안드로이드 액션 바 제목과 아이콘을 변경하는 방법 (0) | 2020.04.26 |
변수 만 참조로 전달해야합니다 (0) | 2020.04.26 |