본문 바로가기
<CPP>/BASIC

7. 조건 체크

by CodeGrimie 2021. 1. 11.

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를 대입하기 위해 변수를 앞에 두는 것이 편하기 때문에 익숙해지는데 시간이 걸린다.

하지만 명확하게 코드 룰이 정해져서 같은 팀의 개발자 모두가 따른다면 코드 룰에서 오류를 최대한 줄일 수 있다.

'<CPP> > BASIC' 카테고리의 다른 글

9. 변수 삼형제  (0) 2021.01.12
8. 함수  (0) 2021.01.12
6. 한글 출력  (0) 2021.01.11
5. 정수  (0) 2021.01.08
4. 출력문  (0) 2021.01.08

댓글