따배씨++ (3.1 Operator Precedence and Associativity)

김동우·2021년 4월 9일
0

안녕하십니까. 김동우입니다.

이번 시간에는 연산자 우선순위와 결합법칙에 대해 얘기하고자 합니다.

바로 코드부터 보여드리겠습니다.

  1. main.cpp
#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;
}
  1. quiz.cpp
#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;
}

우선순위를 외울 필요는 없지만, 알아두는 것은 중요하다는 것을 알게되었습니다.

완벽하게 코딩을 하고 싶다면 적어도 표 정도는 꼭 참고해야겠다는 배움을 얻을 수 있는 시간이었습니다.

그럼 이번 글은 이만 마치도록 하겠습니다. 감사합니다.

0개의 댓글

관련 채용 정보