437
2015-08-19 21:00:11
1
저도 그 글보면서 좀 이건 아니다 싶었어요
내용은 재끼고 중간에 답변중에 비트연산으로 하는 재미난 댓글이 있어서 좀 보다가 댓글 남깁니다.
문제의 답변 코드는 다음과 같은데요
#include <stdio.h>
int main()
{
int i, j;
printf("-----n");
for (i = 0x00477dc4, j = 0x01084210; i; i >>= 1, j >>= 1) {
printf("%c%c", (i&1)*('*'-32) + 32, (j&1)*10);
}
printf("n");
printf("-----n");
return 0;
}
이 코드의 핵심은 글쓴이님께서 생각하신것처럼 비트 연산입니다. 중요한건 i 값과 j 값이죠
먼저 ascii table 에서 * 은 10진수로 42, 스페이스는 32, 그리고 띄어쓰기는 10 입니다.
저 for 문 안에 있는 printf 에서 하는일은 i값과 j 값의 가장 하위 비트를 보고 * 을 찍을건지 스페이스를 할건지 띄어쓰기를 할건지 결정을 합니다.
결론적으로 printf 는 다음과 같은 순서로 동작합니다.
(처음 맨 윗줄만 예를들면 다음과 같습니다.
printf("%c%c", 0x20, 0x00); // 띄어쓰기
printf("%c%c", 0x20, 0x00); // 띄어쓰기
printf("%c%c", 0x3A, 0x00); // *
printf("%c%c", 0x20, 0x00); // 띄어쓰기
printf("%c%c", 0x20, 0x0a); // 띄어쓰기 + 한칸 띄기
이렇게 되면 처음에 두칸 스페이스 , 별(*) , 두칸 스페이스 , 그리고 띄어쓰기가 완성됩니다.
자세히 비트 연산을 통해 살펴 보면 먼저 i 는 0x00477dc4 인데 이를 하위 1바이트만 보면
1 1 0 0 0 1 0 0 과 같이 되어 있습니다. 오른쪽부터 왼쪽으로 하나씩 가신다고 생각하시고 0 이면 띄어쓰기 1 이면 별을 찍습니다.
마찬가지로 j 의 비트 연산을 보면
0 0 0 1 0 0 0 0 과 같이 되어 있고 여기서 오른쪽부터 왼쪽으로 하나씩 간다고 생각하면 0 일때 아무것도 안찍고 1 일때는 한칸 띄어쓰기를 합니다.
저도 초등학교때 이런문제를 본것 같은데 1 중 for문으로도 이렇게 풀리는게 신기하네요 ^^