부록 A — 연산자 조회표
연산자를 설명하는 곳은 본문 49장 「수식과 연산자」다. 그 장은 연산자마다 피연산자 제약·결과 타입·회색지대를 계약으로 적고, 규칙이 왜 그렇게 정해졌는지 까지 다룬다. 이 부록은 그 내용을 되풀이하지 않는다. 여기 있는 것은 코드를 읽다 막혔을 때 눈으로 훑을 한 장짜리 표뿐이다.
플랫폼 노트. 이 부록의 근거
ISO/IEC 9899:2024(C23)의 수식 조항(§6.5)과 대조해 적었다. 인용이 필요하면 부록 D의 안내대로 발행된 표준을 근거로 삼아야 한다.우선순위와 결합
위쪽이 더 강하게 묶는다. 결합 방향은 같은 세기의 연산자가 나란히 있을 때 어느 쪽부터 묶느냐다 — a - b - c가 (a - b) - c인 것은 왼쪽 결합이기 때문이고, a = b = 0이 a = (b = 0)인 것은 오른쪽 결합이기 때문이다.
| 묶음 | 연산자 | 결합 | 결합이 그런 이유 |
|---|---|---|---|
| 후위 | () [] . -> ++(후위) --(후위), 복합 리터럴 | 왼→오 | a.b.c처럼 왼쪽부터 파고들어야 뜻이 선다 |
| 단항 | ++ -- + - ! ~ (타입) * & sizeof alignof | 오→왼 | 피연산자에 가장 가까운 것부터 붙는다: - -x, *&x |
| 곱셈류 | * / % | 왼→오 | 산수의 관례 |
| 덧셈류 | + - | 왼→오 | 뺄셈은 왼쪽 결합이라야 뜻이 맞는다 |
| 시프트 | << >> | 왼→오 | a << 1 << 2는 차례로 민다 |
| 관계 | < <= > >= | 왼→오 | 그래서 x < y < z가 수학과 달라진다 |
| 상등 | == != | 왼→오 | |
| 비트 AND | & | 왼→오 | |
| 비트 XOR | ^ | 왼→오 | |
| 비트 OR | | | 왼→오 | |
| 논리 AND | && | 왼→오 | 단락 평가가 왼쪽부터라야 뜻이 산다 |
| 논리 OR | || | 왼→오 | 같은 이유 |
| 조건 | ?: | 오→왼 | a ? b : c ? d : e가 사다리로 읽힌다 |
| 대입 | = += -= *= /= %= &= ^= |= <<= >>= | 오→왼 | a = b = 0이 “둘 다 0”이 되려면 |
| 쉼표 | , | 왼→오 | 왼쪽을 먼저 하고 버린다 |
표 98.1
자주 미끄러지는 자리들
| 쓴 것 | 실제로 묶이는 방식 | 의도한 것이라면 |
|---|---|---|
a & b == c | a & (b == c) | (a & b) == c |
a << 1 + 2 | a << (1 + 2) | (a << 1) + 2 |
*p++ | *(p++) | (*p)++ |
*p.x | *(p.x) | (*p).x 또는 p->x |
(int)x + y | ((int)x) + y | (int)(x + y) |
a = b = 0 | a = (b = 0) | (그대로다 — 오른쪽 결합) |
x < y < z | (x < y) < z | x < y && y < z |
!x & y | (!x) & y | !(x & y) |
sizeof a + 1 | (sizeof a) + 1 | sizeof(a + 1) |
a ? b : c = d | (a ? b : c) = d(대개 오류) | a ? b : (c = d) |
표 98.2
특히 첫 두 줄은 C의 유명한 설계 흠으로 꼽힌다 — 비트 연산자가 비교 연산자보다 약하게 묶이는 것은 초기 C가 &&·||를 갖기 전의 흔적이다. 그래서 비트 검사에는 괄호가 사실상 필수다. 표준도 각주에서 a<b<c가 수학과 다르게 읽힌다는 것을 따로 짚어 둔다.
더 볼 곳
| 찾는 것 | 갈 곳 |
|---|---|
| 연산자별 계약(피연산자·결과·회색지대) | 49장 「수식과 연산자」 |
| 대입과 부수효과, 평가 순서 | 34장 |
| 포인터 산술의 규칙 | 38장 |
| UB·미지정·구현 정의의 구별 | 52장 |
| 구현이 정해 밝혀야 하는 항목들 | 부록 D |
표 98.3