안녕하십니까. 김동우입니다.
이번 시간에는 연산자 우선순위와 결합법칙에 대해 얘기하고자 합니다.
바로 코드부터 보여드리겠습니다.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int x( 4 + 2 * 3 ); // add(4, mult(2,3)) = 4 + 2 * 3
// 컴파일러는 연산의 우선수위를 그래프화하여 결정한다.
// 결정방식은 자료구조를 통해 배울 수 있다.
// 사칙연산 사이의 결정은 수학에서의 연산순서를 따라간다.
cout << x << endl; // output : 10
int x2( 3 * 4 / 2);
// 연산자 결합법칙(Associativity)은 컴파일러가 어떻게 판단하는지를 알아야 한다.
// https://ko.wikipedia.org/wiki/C%EC%99%80_C%2B%2B%EC%9D%98_%EC%97%B0%EC%82%B0%EC%9E%90
// 링크를 참고하면 C++에서의 우선순위를 볼 수 있다.
// level 5, *,/, Associativity : left-to-right
// 즉, 5순위의 우선순위를 가지며, 왼쪽에서 오른쪽으로 순차적으로 진행된다.
// (3*4)/2 의 순서로 계산이 된다.
// 물론 3*(4/2)의 경우에도 값은 같지만, 단순한 정수 연산에서의 일치였을 뿐이고,
// double의 연산에서는 또 다른 값을 보게 된다.
cout << x2 << endl; //output : 6
int x3 = -3; // unary minus operator right - to - left 순으로 연산
// 오른쪽 정수에 대한 왼쪽 부호의 연산이기 때문에 단항연산은 R to L로 이루어진다.
// + ternary operator ?: 또한 마찬가지다.
// = operator 또한 우항연산 이후 좌항에 대입하는 것이기 때문에 R to L 이다.
// 코딩을 할 때 Associativity를 외우지 말고, 괄호로 명확하게 제한해보자.
// 남의 코드는 아닐 수 있으니 표를 열어보는 것 또한 다른 방법이 된다.
// ^ operator의 경우 논리연산 Bitwise XOR이 된다. 제곱이 아니다. 주의.
// 제곱의 경우 cmath library를 가져와 std::pow를 활용하자.
int x4 = std::pow(4,4); // return double;
cout << x4 << endl; // output : 256
return 0;
}
#include <iostream>
using namespace std;
int main()
{
//(quiz) Associativity를 생각해보자.
// r = 1 + 2 + 3 * 4;
// x = y = z;
// t /= --w + 5;
// a || b && c || d;
int r(1 + 2 + 3 * 4);
// 예상 : 1 + 2 + (3 * 4) -> 12 + 1 + 2 = 15
cout << r << endl;
// output : 15
int x(1);
int y(2);
int z(3);
x = y = z;
// 예상 : (x = y) -> (y = z) -> (x = z) = 3
cout << x << endl;
// output : 3, (y = z) -> (x = y), '=' operator R to L
int w(3);
float t(14);
t/= --w + 5;
// 예상 : 14/{(3-1)+5} = 2 -> t = 2; 우항연산 이후 나눗셈 할당
// /=의 경우 17 level, --는 3 level +(다항연산)의 경우 6 level 의 우선순위
// 즉 할당은 가장 낮은 우선순위고, 나머지 연산은 상위 레벨 우선순위의 연산이다.
cout << t << endl;
// output : 2
bool a(false);
bool b(true);
bool c(false);
bool d(true);
cout << boolalpha;
// true false 출력으로 변환
cout << (a || b && c || d) << endl;
// 예상 : {(a || b) && (c || d)} = true
// output : true
// 실제 실행 순서 : {a || (b && c) || d}
// 1. (b && c) => false, 논리 AND 먼저(level 14)
// 2. a || false(= b && c) => false, 좌측 논리 OR 연산(level 15)
// 3. false(= a || false) || d => true // 우측 논리 OR 연산(L to R)
// 예상과는 사뭇 다른 결과들을 볼 수 있다.
return 0;
}
우선순위를 외울 필요는 없지만, 알아두는 것은 중요하다는 것을 알게되었습니다.
완벽하게 코딩을 하고 싶다면 적어도 표 정도는 꼭 참고해야겠다는 배움을 얻을 수 있는 시간이었습니다.
그럼 이번 글은 이만 마치도록 하겠습니다. 감사합니다.