上个学期我参加了一个操作系统课程。我并不感到惊讶的是,整个班级都是用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代码做过的最酷的事情! 谁能向我解释这是怎么做到的?
[编辑:为了清晰起见调整了缩进]
答案 0 :(得分:1)
一个提示,请考虑数组output
的二进制表示。这种技术出现的地方在于控制硬件寄存器中的位,就像在嵌入式系统中那样 - 这是C真正发光的地方。
答案 1 :(得分:1)
是的,我看到现在看起来很容易。
所以基本上他将char指针赋给输出并在for循环中运行它。 对于它击中的每个十六进制数,它将它向右移动i次,我从7开始,并且i> = 0
所以例如
./bits 0xe7 shift 7
============<<0xe7>>============
Decimal: 231
Bits: [11100111]
==========<<Shifted>>===========
Decimal: 1
Bits: [00000001] >> 7
然后他继续和&amp; (和)结果为1,在这种情况下将返回
00000001
00000001
--------
1
bang(!)字符的绘制取决于我们的结果,并且为结果提供'0'或'1',因为最后但并非最不重要的是他将shift /和结果添加到十六进制数0x20。
0x20是十进制数32,具有白色空格的字符表示,所以如果并且恰好返回0我们只是绘制一个空格,否则添加1个,我们得到十进制数33,它有一个字符爆炸的表现。
当然,有几点需要注意,比如你们都指出有终止值0x00和0x01来表示换行符。
在每行中,他打印32个字符,或4 * 8,因为他为每个十六进制值打印了8个字符。
感谢大家提出我自己的解决方案,因为这比获得答案更有趣;)