. 설명 가능한 소스

GetLineSub 함수의 마지막 조건문을 다시 보도록 하자.

 

     if (nWrap == 1 || EndPos == NULL) {

          p=p;

     } else {

          p=EndPos;

     }

 

이 문장은 for 루프의 바깥에 있는데 이 상태에서 p는 루프를 탈출할 때의 위치를 가지며 EndPos는 탈출하기 전 마지막으로 선정한 후보 위치를 가지고 있을 것이다. 이 조건문은 두 위치 중 하나를 조건에 따라 선택하는 역할을 하며 이 구문을 말로 표현한다면 다음과 같다.

 

글자 정렬이거나, 단어 정렬이더라도 후보 위치를 찾지 못했으면 잘려진 위치 p를 취하고 그렇지 않으면 EndPos를 취한다.

 

이미 이해한 내용이기는 한데 이 구문에서 p=p라는 별 이상한 코드가 좀 의아스럽다. p p를 대입한다니 왜 이런 짓을 하는가? 이 코드는 전혀 쓸데없는 코드가 분명하며 아무 일도 하지 않는 NULL코드이다. 그래서 이 대입문은 빼고 다음처럼 고쳐 써도 된다.

 

     if (nWrap == 1 || EndPos == NULL) {

     } else {

          p=EndPos;

     }

 

그런데 이렇게 쓸 바에야 else문도 필요가 없지 않은가? 그렇다면 이 문장은 아예 다음처럼 쓸 수도 있다.

 

     if (!(nWrap == 1 || EndPos == NULL))

          p=EndPos;

     if (nWrap != 1 && EndPos != NULL))

          p=EndPos;

 

!(A || B) 논리식은 곧 !A && !B와 같기 때문이다. 오른쪽의 코드가 가장 간단한 형태이며 브레이스까지 빼버리면 불과 두 줄밖에 안된다. 이 문장을 말로 표현해보면 다음과 같다.

 

글자 정렬 상태가 아니고 후보 위치가 없지 않으면 EndPos를 취한다. 그렇지 않으면 아무 것도 하지 않고 그냥 p를 그대로 둔다.

 

이 표현은 분명히 틀리지 않은 바른 표현이다. 그러나 앞에서 설명을 전개한 순서와 조건식이 일치하지 않아서 직관적으로 이해하기가 무척 어렵다. 또한 != 조건은 == 조건보다 더 이해하기 어렵고 조건의 범위가 넓어서 분석이 쉽지 않다. 이런 코드는 보는 사람은 물론이고 직접 작성한 사람도 나중에 보면 헷갈리게 된다. 그래서 이해를 돕고자 코드를 좀 풀어 써 놓은 것이고 그러다 보니 p=p 같은 NULL문장을 써 넣게 되었다.

저 코드의 형식에 대해서 이렇게 구질구질한 변명을 늘어 놓는 이유는 앞으로도 저런 코드가 많이 나오기 때문이다. 이 책의 예제는 교육을 목적으로 하기 때문에 너무 압축적이거나 불필요하게 어려워서는 안된다. 코드는 물론이고 전체적인 구조나 알고리즘도 마찬가지이다. 그래서 고심 끝에 좀 비효율적이더라도 읽기 쉽도록 풀어쓰고자 노력하였다. 실력있는 사람들이 보면 굉장히 마음에 안 들고 어색할 수도 있겠지만 이유가 있어 그런 것이니 이해하기 바란다.

참고로 p=p라는 대입문은 컴파일러에 의해 완전히 무시되므로 프로그램의 용량을 낭비하지도 않으며 실행 시간을 축내지도 않는다. 없는 문장이나 마찬가지이며 p를 그대로 둔다는 의미의 주석문이라고 볼 수 있다.