7. 조건 체크
C와 CPP에서 조건 체크는 조금 재미난 기믹이 있다.
특히 C의 경우엔 문법 자체가 정말 간결해서 하루면 다 설명할 수 있을 정도인데 그중에서도 조건 체크는 정말 간단하다.
물론 모든 언어가 문법을 아는 것과 잘 쓰는 건 다른 문제라는 걸 잊지 말자.
▼ CPP에서 조건 체크의 기본적인 코드
#include <cstdio>
#include <clocale>
int main()
{
int a;
a = 5;
if (4 == a)
printf();
return (0);
}
CPP에서 조건 체크는 0인지 아닌 지만 확인한다.
▼ CPP에서 조건 예시
#include <cstdio>
#include <clocale>
int main()
{
_wsetlocale(LC_ALL, L"Korean");
int a;
wprintf(L"정수 a를 입력하세요.\n");
scanf("%d", &a);
if (a > 10)
wprintf(L"a가 10보다 큽니다.\n");
else
wprintf(L"a가 10보다 작습니다.\n");
return (0);
}
C와 CPP에서 내가 가장 실수가 잦은 부분은 조건문이라고 생각한다.
아마 논리연산과 가장 연관되어 있는 데다 내가 논리력이 꽝이라서 그럴 거라 생각한다.
그에 비해 정작 CPP의 조건문은 정말 간단한 절대적인 룰 하나만 따르는 간단한 녀석이다.
오로지 0인지 아닌지만 확인한다.
이게 얼마나 간단하면서 저는지 아래와 같이 코드를 작성해도 된다.
▼ CPP의 하드보일드한 조건 체크 예시
int strlen(const char *str)
{
int length;
length = 0;
while (*(str++))
length++;
return length;
}
한 문자열의 길이를 체크하는 strlen 함수에서 while 문 안의 조건 체크하는 부분을 유심히 보자.
이는 문자열을 이해해야 하는 조금 어려운 예시에 들어가지만 문자열 끝은 언제나 ' \0(NUL) '값인 것만 이해하면 된다.
그리고 ASCII 코드에서 ' \0(NUL) '은 정수로 0이다.
▼ 결국 문자열 ' \0 '은 0이다.
ASCII 코드에서 NUL이 0 인건 C와 CPP에게 있어서는 궁합이 잘 맞는 사이라고 볼 수 있다.
문자열을 처리할 때 별도의 추가적인 작업 없이 곧바로 문자열 끝을 확인할 수 있기 때문이다.
이런 대전제만 확인하는 자유로운 조건 체크는 C와 CPP에게 편한 점도 주지만 치명적인 단점이 되기도 한다.
조건 체크가 너무나도 자유롭게 되어있는 탓에 심각한 오류를 발생하는 경우도 많았다.
아래의 코드를 살펴보자.
▼ 이런 코드도 실행은 된다.
#include <cstdio>
#include <clocale>
int main()
{
_wsetlocale(LC_ALL, L"Korean");
int a;
if (a = 4)
wprintf(L"%d 뭐가 문제죠?\n", a);
if (a = 0)
wprintf(L"%d 뭐가 문제죠?\n", a);
return (0);
}
최근의 비주얼 스튜디오 2019와 같은 IDE들은 이런 코드가 있다면 경고 표시를 해준다.
그렇다고 컴파일이 아예 안 되도록 하지는 않는데 그 이유가 문법적으로 봤을 때는 아무 문제가 없기 때문이다.
앞서서 말했듯이 CPP는 조건이 0인지 아닌지만 확인한다.
컴파일러가 코드를 분석하는 단계에서 a = 4는 a에 4를 대입한다. 그런 다음 a라는 조건을 확인한다.
a에 4가 대입되었으니 0이 아니고 컴파일러는 문제없다 생각하고 다음 코드를 실행한다.
이것이 바로 대입 연산자와 비교 연산자를 잘못 적었을 때 나오는 가장 흔한 실수 중 하나다.
그래서 C99의 오류를 최소화하기 위한 코드 권장 방식에서는 아래와 같은 방법이 나오기도 했다.
▼ 숫자에는 대입이 안 된다는 걸 역이용한 오류 방지 방법
#include <cstdio>
#include <clocale>
int main()
{
_wsetlocale(LC_ALL, L"Korean");
int a;
a = 4;
if (4 == a) // OK
wprintf(L"%d는 4입니다.\n", a);
if (4 = a) // ERROR
wprintf(L"%d는 컴파일 되지 않습니다.\n", a);
return (0);
}
실제로 이런 코드 룰을 적용하면 현저하게 비슷한 실수를 줄일 수 있다.
다만 사람의 말은 a에 4를 대입하기 위해 변수를 앞에 두는 것이 편하기 때문에 익숙해지는데 시간이 걸린다.
하지만 명확하게 코드 룰이 정해져서 같은 팀의 개발자 모두가 따른다면 코드 룰에서 오류를 최대한 줄일 수 있다.