#include <stdio.h>
int main(void)
{
int a = 0, b = 0;
b = a && (a += 1);
printf("%d %d", a, b);
return 0;
}
여기서
분명히 구글에 나오는 연산자 우선순위에 의하면 괄호는 최우선적으로 계산되어야 하잖음? 즉 a+=1이 가장 먼저 계산되어서 a는 1이 나오고, 그다음 논리곱을 계산해서 1&&1이 되어서 참이되고 b에도 1이 들어가 답이 1 1 로 나와야되는데 왜 0 0 이 나옴??
오우야... 걍 a+=1이 가장 먼저 수행되면 그런작업은 분리하도록 해요
short circuit evaluation - return 0;
... 대형사고칠 큰 인재로고...
괄호가 최 우선이라는건 그 의미가 아닌걸 - 164260의 휘발성 계정
제가 곧 시험인데요 ㅠㅠ 괄호가 먼저 계산되는게 저 의미가 아니면 어떤 의미인가요?
컴파일러 마다 다름 a+=1 이란 작업을 뒤로 밀어서 작업 하는 경우도 있고, 먼저 작업하는 경우도 있고
이거슨 어셈으로 봐야 정확히 해결되는 문제임 애초에 저런 코드를 만들면 안되는 것임
저딴 좆같은 문제를 어려운 문제다 라고 내는 교수들도 빠따 맞아야하는 부분 ㅇㅈ? ㅇㅇㅈ!
그럼 일단 급한대로 cygwin에서는 어떤식으로 생각해야 되는건가요? 무조건 왼쪽에서 오른쪽부터 연산하는데 괄호는 그냥 한번에 계산해주는 개념인가요?
컴파일러는 gcc쓰는데..
일단 이유는 안다. 저게 저런 결과가 나오는 이유는 && 논리연산은 && 앞을 먼저 평가하고, 이게 false면 뒤는 무시함. 앞이 true면 그제서야 && 뒤쪽을 평가하게 되는거임. 즉, ()는 무작정 우선순위를 가지는게 아니라, 그냥 그룹화의 역할정도로 보면 됨. 그러니까 a=1-(2+3)이라는 식이 있을때, 2+3이 먼저 되는게 아니라 1과 -를 먼저 스택에 넣고, 그다음 괄호를 인식해서 2+3을 보고 이걸 먼저 연산하는거임. 즉, 결과적으로 ()가 우선순위가 생기는거지, 모든걸 씹어먹고 괄호부터 먼저 실행한다는 뜻이 아님.
참고로 &&가 앞부분 평가에 따라 뒤를 하지 않는 이유는 당연히 퍼포먼스 때문임. 어차피 앞이 false면 뒤의 결과를 보지 않아도 결론은 false잖아. 반대로, ||은 앞이 true면 뒤의 결과를 연산하지 않음. 이게 소소해 보이지만, 이걸 몰라서, 혹은 언어에 따라 이게 안돼서 개판되는게 종종 있음.
참고로 VB6, VBA에는 이 개념이 없다. 근데 VB.NET에서는 이 개념을 추가함. 즉, "And/Or"연산은 VB6/VBA/VB.NET 모두에서 "비트연산"임. if문에 쓰건 할당문에 쓰건 무조건 비트연산임. 그런데 C계열에서의 && ||이 없으니까 퍼포먼스 하락과 불편함이 생기니까, VB.NET 에서는 AndAlso와 OrElse라는 "논리연산"을 추가함. 내가 말한 딱 저 이유와 목적으로 쓰는거임.
아, 그리고 내가 퍼포먼스 하나 때문인것처럼 위에 썼는데, 쓰다보니 깜빡한거고, 퍼포먼스도 문제지만, 여러가지 짜다보면, 저 개념이 "필수적"이라는걸 알게됨. 즉, 앞부분이 true가 아니면 뒷부분 실행하게 되면 에러나 버그가 발생하는 상황이 있음. 이럴때 &&로 묶어주는거지. 앞부분에서 flag같은걸 확인하고 뒷부분을 실행하는 상황. true면 문제가 없고, false면 뒷부분을 실행하지 않아서 에러 발생을 방지함. 그리고 || 은 보통 둘 다 실행인 경우인데, 앞부분이 안되는 거면 뒷부분이라도 실행시켜서 처리한다는 개념에서 쓰고. 물론 앞부분이 실행되면 뒷부분은 실행되지 않음. 다 쓸모가 있음.