在 C 中使用 unsigned char 进行神奇打印
Posted
技术标签:
【中文标题】在 C 中使用 unsigned char 进行神奇打印【英文标题】:Magical printing with unsigned char in C 【发布时间】:2013-10-10 20:16:44 【问题描述】:上学期我上了操作系统课。我对整个班级都是用 C 语言教授的并不感到惊讶,但它的大量使用似乎让班上的一些人感到厌烦。课程结束后,一些不喜欢这门语言的人大声疾呼,他们不必再次用 C 编程是多么高兴。这引发了学生(和老师)之间的一场小辩论,最终以一位教授该课程的老师的回复结束。他的答案是用 C 代码写的:
#include <stdio.h>
unsigned char output[] =
0xe7, 0x3a, 0x1d, 0x2f, 0x01,
0x92, 0x42, 0x09, 0x48, 0x01,
0x92, 0x32, 0x09, 0x8e, 0x01,
0x92, 0x0a, 0x09, 0x48, 0x01,
0xe7, 0x73, 0xdd, 0x2f, 0x00,
;
int main()
unsigned char* wb;
int i;
for (wb = output; *wb; wb++)
if (*wb == 0x01)
printf("\n");
continue;
for (i = 7; i >= 0; i--)
putchar((((*wb >> i) & 1) + 0x20));
printf("\n");
return 0;
打印出来:
!!! !!! !!! ! !!! ! ! !!!!
! ! ! ! ! ! ! ! !
! ! ! !! ! ! !! !!!
! ! ! ! ! ! ! ! !
!!! !!! !!! !!!! !!! ! ! !!!!
这是我一生中见过的任何人用 C 代码做的最酷的事情!!! 谁能给我解释一下这是怎么做到的?
[编辑:为清晰起见调整了缩进]
【问题讨论】:
解开混淆代码是为了好玩。使用调试器并回答您自己的问题。我会赞成答案。顺便说一句,C 是一种很好的基础语言:UNIX 就是用它编写的。 好吧,我更多的是寻找提示而不是完整的解释。我同意,这更有趣:) 两条线索:0x00 是数据块中的终止条件,>> 是按位移位,但要注意运算符优先级。这真的很容易。现在把那个调试器拿出来。 【参考方案1】:一个提示,考虑数组output
的二进制表示。这种技术出现的一个地方是控制硬件寄存器中的位,就像您在嵌入式系统中所做的那样 - 这是 C 真正发光的地方。
【讨论】:
【参考方案2】:是的,我发现在研究之后现在很容易。
所以基本上他将 char 指针分配给输出并在 for 循环中运行它。 对于它击中的每个十六进制数,它向右移动 i 次,i 从 7 开始并且 i > = 0
例如
./bits 0xe7 shift 7
============<<0xe7>>============
Decimal: 231
Bits: [11100111]
==========<<Shifted>>===========
Decimal: 1
Bits: [00000001] >> 7
然后他继续用 1 和 & (ands) 结果,在这种情况下会返回
00000001
00000001
--------
1
Bang (!) 字符的绘制取决于结果,并为我们提供“0”或“1”作为结果,因为最后但并非最不重要的是,他将移位/和结果添加到十六进制数 0x20。
0x20 是十进制数 32,具有空格的字符表示,所以如果 and 恰好返回 0,我们只需绘制一个空格,否则添加 1,我们得到十进制数 33,它有一个字符爆炸的表示。
当然,有几件事需要注意,就像你们都指出的那样,终止值 0x00 和 0x01 表示换行符。
在每一行中,他打印 32 个字符,或 4 * 8,因为他为每个十六进制值打印 8 个字符。
感谢你们提出我自己的解决方案,因为这比获得答案更有趣;)
【讨论】:
以上是关于在 C 中使用 unsigned char 进行神奇打印的主要内容,如果未能解决你的问题,请参考以下文章