[퀴즈] 프로그래머를 위한 문제 #4 - 또라이 같은 C 언어 코드를 설명하라
재미있는 C 언어 문제
인터넷 RSS 피드를 구독해서 보다가 재미있는 C 언어 코드를 발견했다. 조금 난해하게 보이는 코드다. 이런 코드로 신입 개발자 면접 시험을 보면 재미있겠단 생각이 든다.
문제의 C 언어 코드는 다음과 같다. 소스 코드와 실행 결과가 전혀 매치가 안되는 이 또라이 같은 코드를 보고 순간 멈칫 할 것이다. 하지만 조금 귀 기울여 보면 말 되는 코드다.
이 링크를 클릭하면 즉시 컴파일 된 실행 결과도 함께 볼 수 있다.
main()
{
int a,b,c;
int count = 1;
for (b = c = 10;
a = "- FIGURE?, UMKC,XYZHello Folks,\
TFy!QJu ROo TNn(ROo)SLq SLq ULo+\
UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^\
NBELPeHBFHT}TnALVlBLOFAkHFOuFETp\
HCStHAUFAgcEAelclcn^r^r\\tZvYxXy\
T|S~Pn SPm SOn TNn ULo0ULo#ULo-W\
Hq!WFs XDt!"[b+++21]; )
for(; a-- > 64 ; )
putchar ( ++c=='Z' ? c = c/ 9:33^b&1);
return 0;
}
/* 실행 결과
!!!!!!
!!!!!!!!!!
!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!
!!!!!!!!!!!!
!!!!!!!!!!!!
!!!!!!!!!!!!
!!!!!!!!
!!!!!!!!!!
!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!! !!!!!
!!!!!!!!!!!!!!!!!!! !!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!! ! !!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!
!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !
!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!
!!!!!!!!!!!!
!!!!!!!!!!!!
!!!!!!!!!!!!
!!!!!!!!
!!!!!!
!!!!
*/
코드 분석
이 코드는 C 언어 문법에 어긋나지 않지만 알아보기 힘들게 교묘하게 섞어 놨다. 잘 보면 위의 코드를 이해할 수 있는 몇 가지 단서를 발견할 수 있다.
1. 문자의 배열
이 코드를 잘 보면, for (b = c = 10; a = "- FIGURE?, .. 중간 생략 .. Hq!WFs XDt!"[b+++21]; )
a 변수에 대입 되는 값은 "...문자열..."[인덱스]
값인 char 문자가 된다.
b = 10
초기 값을 가지므로 배열의 인덱스 값은 [11+21]
, 즉 32번 문자부터 시작하므로 a 변수의 문자열 "- FIGURE?, UMKC,XYZHello Folks,\"
은 그냥 더미(쓰레기) 값임을 알 수 있다.
2. 섞어 놓은 문법 풀기
이 코드에서 for (b = c = 10; a = "- FIGURE?, .. 중간 생략 .. Hq!WFs XDt!"[b+++21]; )
배열 인덱스를 나타내는 [b+++21]
코드는 [(b++)+21]
로 풀어 쓸 수 있다.
putchar ( ++c=='Z' ? c = c/ 9:33^b&1);
코드는 일반적인 삼항식이다.
삼항식인 ++c=='Z' ? c = c/ 9:33^b&1
코드는 (++c == 'Z') ? (c = c / 9) : (33 ^ b & 1)
이렇게 풀어 쓸 수 있다.
이 두 가지의 문법적인 부분만 발견하고 풀어냈다면 다 한 것이나 다름 없다.
(++c == 'Z')
는 ASCII 코드 표를 참고해 보면 (++c == 90)
이 되고, c = 10
인 초기 값을 갖는다. 그러므로 80번 반복 후에 c=c/9
코드의 값은 언제나 10=90/9
이 되므로 10인 ASCII 코드인 'new line', 새로운 행에서 문자를 계속 찍는다.
(33 ^ b & 1)
코드는 (33 xor b and 1)
비트 연산과 같다. xor, and 연산 중 and 연산이 더 우선 순위이므로 (b and 1) xor 33
이렇게 표현할 수 있겠다.
33 - (b ^ 1)
코드로 최종적으로 표현되는데, b^1
은 홀수면 1, 짝수면 0이 된다. ASCII 코드 표를 참고해 보면 33,32 값은 각각 '!' 문자와 'Space' 문자가 된다.
아래는 ASCII 코드 표 이므로 참고하기 바란다.

코드가 실행되는 순서대로 ASCII 값을 대입해 보면, 코드가 어떻게 실행 결과처럼 출력 되는지 이해할 수 있을 것이다.
보기 쉬운 코드로 변경
코드를 자세히 보니 별 것 아니란 걸 느꼈을 것이다. 이 코드를 리팩토링여 알아보기 쉬운 코드로 아래와 같이 바꿀 수 있다. 그럼 같은 결과를 얻을 수 있다. 혹시 잘 이해가 되지 않는다면 아래의 코드를 if
문법으로 변경해 보면 더 보기 편할 것이다.
int main()
{
int a,b,c;
char *str = "- FIGURE?, UMKC,XYZHello Folks,\
TFy!QJu ROo TNn(ROo)SLq SLq ULo+\
UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^\
NBELPeHBFHT}TnALVlBLOFAkHFOuFETp\
HCStHAUFAgcEAelclcn^r^r\\tZvYxXy\
T|S~Pn SPm SOn TNn ULo0ULo#ULo-W\
Hq!WFs XDt!";
for (b = c = 10; a = *(str + (b++) + 21); ) {
for(; a-- > 64 ; ) {
putchar ( ++c==90 ? c = c / 9 : 33 - (b&1));
}
}
}