Proven C BookEnglish GitHub

부록 A — 연산자 조회표

연산자를 설명하는 곳은 본문 49장 「수식과 연산자」다. 그 장은 연산자마다 피연산자 제약·결과 타입·회색지대를 계약으로 적고, 규칙이 왜 그렇게 정해졌는지 까지 다룬다. 이 부록은 그 내용을 되풀이하지 않는다. 여기 있는 것은 코드를 읽다 막혔을 때 눈으로 훑을 한 장짜리 표뿐이다.

플랫폼 노트. 이 부록의 근거

ISO/IEC 9899:2024(C23)의 수식 조항(§6.5)과 대조해 적었다. 인용이 필요하면 부록 D의 안내대로 발행된 표준을 근거로 삼아야 한다.

우선순위와 결합

위쪽이 더 강하게 묶는다. 결합 방향은 같은 세기의 연산자가 나란히 있을 때 어느 쪽부터 묶느냐다 — a - b - c(a - b) - c인 것은 왼쪽 결합이기 때문이고, a = b = 0a = (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 == ca & (b == c)(a & b) == c
a << 1 + 2a << (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 = 0a = (b = 0)(그대로다 — 오른쪽 결합)
x < y < z(x < y) < zx < y && y < z
!x & y(!x) & y!(x & y)
sizeof a + 1(sizeof a) + 1sizeof(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