Fork me on GitHub

一个有趣的C程序

今天偶然发现了一个有趣的程序,经查找,发现是来自《C专家编程》

根据位模式构建图形图标(icon)或者图形(glyph),是一种小型的位模式映射于屏幕产生的图像。一个位代表图像上的一个像素。如果一个位被设置,那么它所代表的像素就是“亮”的。如果一个位被清除,那么它所代表的像素就是“暗”的。所以,一系列的整数值能够用于为图像编码。类似Iconedit这样的工具就是用于绘图的,他们所输出的是一个包含一系列整型数的ASCII文件,可以被一个窗口程序所包含。它所存在的问题是程序中的图标只是一串十六进制数。

在C语言中,典型的16X16的黑白图形可能如下:

static unsigned short stopwatch[] = {
0x07C6,
0x1FF7,
0x383B,
0x600C,
0x600C,
0xC006,
0xC006,
0xDF06,
0xC106,
0xC106,
0x610C,
0x610C,
0x3838,
0x1FF0,
0x07C0,
0x0000
};
`</pre>
正如所看到的那样,这些C语言常量并未有提供有关图形实际模样的任何线索。

这里有一个惊人的#define定义的优雅集合,允许程序建立常量使它们看上去像是屏幕上的图形。
<pre>`#define X )*2+1
#define _ )*2
#define s ((((((((((((((((0 /* For building glyphs 16 bits wide */
`</pre>
定义了它们之后,只要画所需要的图标或者图形等,程序会自动创建它们的十六进制模式。使用这些宏定义,程序的自描述能力大大加强,上面这个例子可以转变为:
<pre class="">`static unsigned short stopwatch[] =
{
s _ _ _ _ _ X X X X X _ _ _ X X _ ,
s _ _ _ X X X X X X X X X _ X X X ,
s _ _ X X X _ _ _ _ _ X X X _ X X ,
s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,
s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,
s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,
s X X _ X X X X X _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,
s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,
s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,
s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,
s _ _ X X X _ _ _ _ _ X X X _ _ _ ,
s _ _ _ X X X X X X X X X _ _ _ _ ,
s _ _ _ _ _ X X X X X _ _ _ _ _ _ ,
s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
};
`</pre>
显然,与前面的代码相比,它的意思更为明显。

测试结果:
<div align="center">![有趣的C程序](http://www.chenziping.cf/blog/wordpress/wp-content/uploads/2016/07/draw.png)</div>
当然,你也可以用二进制来表示:
<pre>`static unsigned short stopwatch[] = {
0b0000011111000110,
0b0001111111110111,
0b0011100000111011,
0b0110000000001100,
0b0110000000001100,
0b1100000000000110,
0b1100000000000110,
0b1101111100000110,
0b1100000100000110,
0b1100000100000110,
0b0110000100001100,
0b0110000100001100,
0b0011100000111000,
0b0001111111110000,
0b0000011111000000,
0b0000000000000000,
};

但还是没有前面那种巧妙与直观。。

真是有趣!