이 코드는 인도의지도를 인쇄합니다. 어떻게 작동합니까?
#include <stdio.h>
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;
}
답변
긴 문자열은 ASCII로 변환 된 이진 시퀀스입니다. 첫 번째 for
명령문은 b
10에서 시작하고 그 [b+++21]
이후 문자열은 31입니다. 문자열을 배열로 취급하면 오프셋 31은 문자열에서 “실제”데이터의 시작입니다 (제공 한 코드 샘플의 두 번째 줄). 나머지 코드는 단순히 비트 시퀀스를 반복하여 1과 0을!와 공백으로 변환하고 한 번에 한 문자 씩 인쇄합니다.
덜 난독 화 된 버전 :
#include "stdio.h"
int main (void) {
int a=10, b=0, c=10;
char* bits ="TFy!QJu ROo TNn(ROo)SLq SLq ULo+UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^NBELPeHBFHT}TnALVlBLOFAkHFOuFETpHCStHAUFAgcEAelclcn^r^r\\tZvYxXyT|S~Pn SPm SOn TNn ULo0ULo#ULo-WHq!WFs XDt!";
a = bits[b];
while (a != 0) {
a = bits[b];
b++;
while (a > 64) {
a--;
if (++c == 'Z') {
c /= 9;
putchar(c);
} else {
putchar(33 ^ (b & 0x01));
}
}
}
return 0;
}
이상한 영리한 부분은에 putchar
문. 첫 번째를 가져 가라 putchar
. ASCII 'Z'
는 10 진수 90이므로 개행 문자 인 90/9 = 10입니다. 두 번째에서 10 진수 33은의 ASCII입니다 '!'
. 33의 하위 비트를 토글하면 32는 공간의 ASCII입니다. 이 원인은 !
경우 인쇄 할 b
홀수이며, 경우 빈 공간을 인쇄 할 수 b
도있다. 코드의 나머지 부분은 단순히 a
문자열을 통해 “포인터”를 걷는 것 입니다.
답변
기본적으로 문자열은 이미지 의 런타임 길이 인코딩 입니다. 문자열의 대체 문자는 공백을 그리는 횟수와 느낌표를 연속해서 그리는 횟수를 나타냅니다. 다음은이 프로그램의 다양한 요소에 대한 분석입니다.
인코딩 된 문자열
이 문자열의 처음 31자는 무시됩니다. 나머지는 이미지를 그리는 지침을 포함합니다. 개별 문자는 연속적으로 그릴 공백 또는 느낌표의 수를 결정합니다.
외부 for 루프
이 루프는 문자열의 문자를 넘어갑니다. 반복 할 때마다 값이 b
1 씩 증가 하고 문자열의 다음 문자를에 할당합니다 a
.
내부 for 루프
이 루프는 줄 끝에 도달 할 때마다 개별 문자와 줄 바꿈을 그립니다. 그려진 문자 수는 a - 64
입니다. 값은 c
10에서 90으로 바뀌고 줄 끝에 도달하면 10으로 다시 설정됩니다.
그만큼 putchar
이것은 다음과 같이 다시 작성할 수 있습니다.
++c;
if (c==90) { //'Z' == 90
c = 10; //Note: 10 == '\n'
putchar('\n');
}
else {
if (b % 2 == 0)
putchar('!');
else
putchar(' ');
}
b
짝수인지 홀수 인지 또는 필요할 때 줄 바꿈 에 따라 적절한 문자를 그립니다 .