此代码打印印度地图。它是如何工作的?
#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;
}
答案 0 :(得分:153)
长字符串只是转换为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;
}
strange 聪明的部分在putchar
语句中。拿第一个putchar
。 ASCII 'Z'
十进制为90,因此90/9 = 10这是一个换行符。在第二个中,小数33是'!'
的ASCII。切换33的低位为你提供32,这是一个空格的ASCII。如果!
为奇数,则会导致b
打印;如果b
为偶数,则会打印空白区域。代码的其余部分只是将“指针”a
传递给字符串。
答案 1 :(得分:89)
基本上,字符串是图像的run-length encoding:字符串中的交替字符表示绘制空格的次数,以及连续绘制感叹号的次数。以下是对该计划不同要素的分析:
已编码的字符串
忽略此字符串的前31个字符。其余包含绘制图像的说明。单个字符确定连续绘制的空格或感叹号的数量。
外循环
此循环遍历字符串中的字符。每次迭代都会将b
的值增加1,并将字符串中的下一个字符分配给a
。
内循环
此循环绘制单个字符,并在到达行尾时绘制换行符。绘制的字符数为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
是偶数还是奇数来绘制相应的字符,或者在需要时使用换行符。