C의 논리 AND 연산자 &&는 왼쪽 피연산자를 먼저 평가합니다. 왼쪽 값이 0이면 전체 결과는 거짓이므로 오른쪽 피연산자를 평가하지 않습니다. 왼쪽 값이 0이 아니면 오른쪽도 평가하고, 두 값이 모두 0이 아닐 때만 결과가 참입니다.
따라서 정수 분모를 먼저 검사하는 x != 0 && 100 / x > 2는 x가 0일 때 나눗셈을 건너뜁니다. 이 설명은 C11 규칙을 기준으로 하며, 위원회 문서 N1570은 2011년 초안입니다.
좌항 결과가 우항 실행 여부를 결정합니다
&&는 두 조건을 모두 만족하는지 묻지만, 두 조건을 언제나 모두 계산하는 연산자는 아닙니다. C11에서 왼쪽 피연산자는 오른쪽보다 먼저 평가됩니다. 왼쪽이 0이면 오른쪽은 평가되지 않고 결과가 0이 됩니다. 왼쪽이 0이 아니면 오른쪽을 평가해 그 값이 0인지 확인합니다. 이 실행 순서는 우항에 함수 호출이나 위험한 계산이 있을 때 중요합니다. 다만 우항이 건너뛰어진다는 사실만 알고 좌항과 우항의 순서를 바꾸면 안 됩니다.
분모가 0인 입력을 손으로 추적해 봅니다
int x = 0;
int ok = (x != 0 && 100 / x > 2);
printf("%d\n", ok);| x | 왼쪽 x != 0 | 오른쪽 평가 | ok |
|---|---|---|---|
| 0 | 거짓(0) | 건너뜀 | 0 |
| 4 | 참(1) | 100 / 4 > 2, 참 | 1 |
| 60 | 참(1) | 100 / 60 > 2, 거짓 | 0 |
x=0에서는 첫 비교가 0을 만들기 때문에 오른쪽의 나눗셈 표현을 아예 평가하지 않습니다. 따라서 이 예제에서 100 / x가 실행되지 않습니다. x=4이면 우항까지 평가해 정수 나눗셈 결과 25를 비교합니다. x=60이면 C의 정수 나눗셈 결과가 1이므로 비교가 거짓입니다. 표는 평가 여부와 최종 값이 서로 다른 질문임을 보여줍니다.
조건식의 평가 순서와 기록을 확인합니다
- 연산자가
&&인지 확인하고 왼쪽부터 시작합니다. - 왼쪽 피연산자의 실제 값을 계산합니다. 0이면 우항을 적지 않고 전체 결과를 거짓으로 마칩니다.
- 왼쪽이 0이 아닐 때만 오른쪽을 계산하고, 오른쪽이 0인지 판단합니다.
- 필요하면 중간 결과를 표로 남겨 평가 생략과 최종 결과를 분리합니다.
순서를 바꾸면 보호 조건이 사라집니다
100 / x > 2 && x != 0으로 바꾸면 분모 검사를 하기 전에 나눗셈 식을 먼저 평가하게 됩니다. 원래의 안전한 순서는 x != 0이 분모의 조건을 확인하고, 그 조건이 참일 때만 오른쪽 계산을 허용하는 구조입니다. 두 조건을 단순히 나열했다고 생각하지 말고, 위험한 계산이 어느 쪽에 놓였는지 보세요. 또한 &는 정수 비트 연산자이므로 논리 AND의 단락 평가를 대신하지 않습니다.
&&의 순서가 중요한 이유는 좌항과 우항을 아무 순서로나 바꿔도 같은 결과가 나오는 것이 아니기 때문입니다. 왼쪽에는 우항을 안전하게 계산하기 위한 선행 조건을 둡니다. 두 항을 바꾸면 분모가 0인지 검사하기 전에 나눗셈 식이 평가될 수 있습니다. 왼쪽이 참일 때만 오른쪽에 도달하므로 함수 호출이 포함된 조건식은 입력에 따라 호출 횟수도 달라집니다. 출력 문제에서는 최종 0과 1만 쓰지 말고 우항이 실행됐는지도 기록하세요. ||도 왼쪽이 참일 때 오른쪽을 건너뛰는 성질이 있지만, 이 글의 핵심은 &&입니다.
특히 왼쪽 검사와 오른쪽 계산이 모두 정수식일 때에는 각 결과가 0인지 아닌지를 먼저 표시하세요. C의 논리 연산자는 참을 1, 거짓을 0으로 내므로 중간 값을 구한 다음 전체 값을 쉽게 결정할 수 있습니다. 이 단순한 예제에는 함수의 입력 검사나 부작용이 없지만, 실제 코드에서는 오른쪽 함수가 파일을 읽거나 변수를 변경할 수도 있습니다. 단락 평가는 그 함수가 호출되지 않는 경우를 만들 수 있으므로 조건 순서는 동작의 일부입니다.
정답을 가리고 확인해 보세요
이 글을 위해 만든 학습 예시이며 공식 기출문제나 판매 카드의 인용이 아닙니다.
x가 0일 때 x != 0 && 100 / x > 2는 오른쪽 나눗셈을 평가하나요?
정답과 해설 확인
평가하지 않습니다. 전체 논리 AND 값은 거짓(0)입니다.C11에서 &&는 왼쪽을 먼저 평가합니다. 왼쪽이 0이면 오른쪽은 평가되지 않습니다. 이는 해당 입력에 대한 교육용 추적이며 컴파일러의 특정 기계 코드를 주장하지 않습니다.