질문 배경
C에서 연산자의 우선순위는 수학 및 논리 표현식의 계산 순서를 관리하기 위해 도입되었습니다. 수학 연산자가 역사적으로 기대되는 우선순위를 가지지만(대수학처럼), 많은 새로운 연산자(논리, 비트 연산자, 할당 등)가 등장하면서 상황이 복잡해졌습니다. 오류 가능성을 줄이고 가독성을 높이기 위해 공식적인 연산자 우선순위 및 결합 목록이 등장했습니다.
문제
연산자가 많고 그 성격이 다양하기 때문에(산술, 비교, 할당, 논리, 인덱싱) 복합 표현식 작성을 할 때 모호성이 발생합니다. 이들의 적용 순서를 잘못 이해하면 논리적 오류와 항상 명확하지 않은 버그를 초래할 수 있으며, 특히 비트 연산자와 논리 연산자, 포인터, 증감 연산자 및 삼항 연산자가 결합될 때 더욱 그렇습니다.
해결책
코드 예:
#include <stdio.h> int main() { int a = 1, b = 2, c = 3, d; d = a + b * c; // b*c가 먼저 수행됨: d = 1 + (2*3) = 7 printf("%d\n", d); d = a + b << 1; // a + b = 3, 그 다음 3 << 1 (6) printf("%d\n", d); d = a < b ? a++ : b++; printf("%d\n", d); // a < b가 참 => d = a (1), a는 나중에 증가함 }
주요 특징:
괄호를 잊었을 때 표현식 x = y > z ? y : z는 어떤 결과를 줍니까?
답변: 삼항 연산자 ?:의 우선순위는 >보다 낮습니다. 먼저 (y > z)가 вычисляется, 그 다음 y와 z 중 하나가 선택됩니다. 그러나 할당과 조합하면 예상치 못한 결과가 발생할 수 있습니다. 항상 괄호를 사용하는 것이 좋습니다 x = (y > z) ? y : z;.
*표현식 p++의 결과는 무엇이며 그 이유는 무엇입니까?
답변: 후위 증가 연산자 (++)의 우선순위가 역참조 (*보다 높기 때문에 *p++은 *(p++): 먼저 p가 사용되고 증가한 다음 역참조됨, 이는 *++p와 다를 수 있습니다(증가 후 역참조).
표현식 a & b == c는 왜 예상대로 작동하지 않습니까?
답변: 연산자 ==의 우선순위가 &보다 높기 때문에 표현식은 a & (b == c)로 분석되며 (a & b) == c로 분석되지 않으므로 예상치 못한 결과를 초래할 수 있습니다. 원하는 논리를 위해서는 괄호를 사용해야 합니다.
if ((a & b) == c) { ... }
부정적인 경우
코드를 최적화하던 개발자가 괄호 없이 여러 연산자를 결합했습니다: if( mask & flag == 0 ) ..., 그 결과 확인 로직이 잘못되어 시스템이 오류가 발생했습니다.
장점:
단점:
긍정적인 경우
명시적인 그룹화를 사용: if( (mask & flag) == 0 ) ..., 로직이 명확하고 플래그 변경이 용이합니다.
장점:
단점: