나는 초보자 실수를 생각하고 있었고 if
성명서 에서 실수로 끝났습니다 . 코드를 조금 확장했습니다.
int i = 0;
if (i = 1 && i == 0) {
std::cout << i;
}
나는이 본 if
문 반환 사실, 그것은 cout
의 i
로 1
. 경우 i
할당 1
한 이유는 if 문에서 i == 0
수익을 true
?
1 && i == 0
합니까?
나는 초보자 실수를 생각하고 있었고 if
성명서 에서 실수로 끝났습니다 . 코드를 조금 확장했습니다.
int i = 0;
if (i = 1 && i == 0) {
std::cout << i;
}
나는이 본 if
문 반환 사실, 그것은 cout
의 i
로 1
. 경우 i
할당 1
한 이유는 if 문에서 i == 0
수익을 true
?
1 && i == 0
합니까?
답변:
이것은 연산자 우선 순위 와 관련이 있습니다 .
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
.
i = !i; 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
.
using namespace std
!
=
이전에 생각한 사람 &&
이 문제를 볼 수 있습니다. 또한 그렇습니다. 확장이 외래이지만 그다지 중요하지 않다고 생각합니다. 나는 그러한 사소한 차이로 인해 사람들이 151에서 -4로 투표한다고 믿을 수 없습니다.
오른쪽에서 왼쪽으로 규칙을 구문 분석하는 것과 관련이 있습니다. 예를 들어 y = x + 5입니다.
모든 하위 표현의 중요성이 중요합니다. 똑같이 중요한 두 가지 표현이 오른쪽에서 왼쪽으로 평가됩니다. && 표현식 측면이 먼저 수행 된 후 LHS가 수행됩니다.
이해가 되네요
실제 답변은 다음과 같습니다.
증거로, 입력 한 코드에 대한 컴파일러의 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 ++ 임)
컴파일러는 실제로 i = 1을 설정하지 않았지만 i = TRUE (정수 값이 아닌 32 비트를 의미 함)입니다. 이는 && 연산자가 명령문이 TRUE인지 FALSE인지 평가 한 후 해당 결과에 따라 결과를 설정하기 때문입니다. 증거로 i = 1을 i = 2로 변경하면 아무것도 변하지 않을 것이라는 것을 스스로 확인할 수 있습니다. 컴파일러 탐색기 에서 온라인 컴파일러를 사용하여 직접 확인하십시오
i = 1
할당 (등가 아님) 연산자; 2b) if (i = 0)
C와 C ++에서 모두 거짓 상태로 평가 될 것이라고 확신 할 수 있으므로 "실패하지 않는다"고 진정한 wrt로 평가되는지 여부는 다소 오해의 소지가 있습니다.
and cl, 1 ; = operator always TRUE
<< 내가 틀렸다면 정정하되, 여기서 할당이 보이지 않습니다. 1 &&
표현식 의 일부를 나타냅니다 . 따라서이 답변은 기본적으로로 평가됩니다 false
.
if ( i = 0 ) { print something }
. 또한 당신의 대답은 모순됩니다; 처음에는 i=1
이전에 평가 되었다고 말한 &&
다음 연산자 i
의 결과로 설정 되었다고 말합니다 &&
.
i
설정되어 있기 때문에 if 코드가이 코드로 입력 된 이유를 알고 싶어 합니다1
.