在 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 进行神奇打印的主要内容,如果未能解决你的问题,请参考以下文章

在C语言中,unsigned char是啥类型

在C语言中,unsigned char是啥类型

如何获取一个unsigned char*类型的字符串长度

在C语言中,unsigned char是啥类型?

在C语言中,unsigned char是啥类型

什么是unsigned char;;?