식은 순서대로 줄어든다
Esc

    식은 순서대로 줄어든다

    –C#기초

    앞 글에서 기호를 하나씩 봤습니다. 이제 여러 개가 한 줄에 섞이면 어떻게 되는지 봅니다.

    int r = 3 + 4 * 5;

    23 입니다. 왼쪽부터 읽었다면 35 가 나왔을 겁니다. 컴파일러는 한 줄을 왼쪽부터 읽지 않습니다.

    식은 우선순위가 높은 곳부터 값으로 바뀌고, 값 하나만 남을 때까지 줄어듭니다.

    식은 값 하나로 줄어든다

    3 + 4 * 5 가 계산되는 과정을 한 단계씩 보겠습니다. 색이 칠해진 부분이 이번 단계에서 계산되는 곳입니다.

    세 번째 것이 앞 글에서 결과가 갈렸던 이유입니다.

    double r1 = (double)a / b;     // 3.3333...  캐스팅이 먼저
    double r2 = (double)(a / b);   // 3          나눗셈이 먼저

    (double)(a / b) 는 정수로 나눈 뒤에 실수로 옮기니 이미 늦었습니다. 같은 글자로 되어 있는데 괄호 위치 하나가 결과를 바꿉니다.

    외우지 말고 괄호를 쓴다

    우선순위 표는 이렇습니다. 앞 글에서 본 기호들을 순서대로 놓은 것입니다.

    순서 연산자
    1 ( ) 괄호
    2 ! ++ -- (타입) 캐스팅
    3 * / %
    4 + -
    5 < > <= >=
    6 == !=
    7 &&
    8 ||
    9 = += -= 대입

    외울 필요 없습니다. 알아둘 건 두 가지뿐입니다.

    • 산술이 비교보다 먼저고, 비교가 논리보다 먼저고, 대입이 맨 마지막입니다. if (a + 1 > b && c) 가 괄호 없이 되는 이유입니다
    • 나머지는 헷갈리면 괄호를 치세요. 괄호를 친 코드가 진 적은 없습니다
    bool r = true || false && false;     // 헷갈립니다
    bool r = true || (false && false);   // 같은 뜻인데 읽힙니다

    && 가 || 보다 먼저라 둘은 같은 식입니다. 그런데 읽는 사람은 그걸 모릅니다.

    대입이 맨 마지막인 것도 이제 말이 됩니다. int r = 3 + 4 * 5; 에서 오른쪽이 값 하나로 다 줄어든 다음에야 r 의 자리에 씁니다.

    && 는 오른쪽을 안 볼 수도 있다

    순서 이야기의 마지막입니다. 어떤 부분은 아예 계산되지 않습니다.

    왼쪽만으로 결과가 정해지면 오른쪽은 실행되지 않습니다.

    && 는 왼쪽이 거짓이면 오른쪽이 뭐든 거짓입니다. 그래서 안 봅니다. || 는 왼쪽이 참이면 오른쪽을 안 봅니다. 단축 평가라고 합니다.

    현금이 있고 시간이 되면 간다고 할 때, 현금이 없으면 시간은 확인도 안 하는 것과 같습니다.

    이게 단순한 최적화가 아니라 자주 쓰는 안전장치입니다.

    null 검사를 먼저 두고 바로 뒤에서 그 객체를 쓸 수 있는 이유가 단축 평가입니다. 순서를 뒤집으면 검사가 있으나 마나입니다.

    정리

    • 식은 우선순위가 높은 곳부터 값으로 바뀌고, 값 하나만 남을 때까지 줄어든다.
    • 괄호는 새 규칙이 아니라 그 순서를 직접 정하는 도구다. 헷갈리면 괄호를 쓴다.
    • 산술 → 비교 → 논리 → 대입 순이다. 대입이 맨 마지막이라 오른쪽이 다 줄어든 뒤에 쓴다.
    • 캐스팅이 나눗셈보다 늦으면 아무 의미가 없다.
    • && 와 || 는 왼쪽으로 결과가 정해지면 오른쪽을 실행하지 않는다.