Reputation: 657
Last semester I took a class in operating systems. I wasn't surprised that the whole class was taught in C but the heavy use of it seemed to annoy some people of the class. When the course was over couple of those who disliked the language were raising their voices about how happy they were not having to have to program in C again. This started a small debate between students (and teachers) which ended with a reply from one of the teacher who taught the course. His answer was written in C code:
#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;
}
This prints:
!!! !!! !!! ! !!! ! ! !!!!
! ! ! ! ! ! ! ! !
! ! ! !! ! ! !! !!!
! ! ! ! ! ! ! ! !
!!! !!! !!! !!!! !!! ! ! !!!!
which is about the coolest thing I've seen anyone do in C code my entire life!!! Can anyone explain to me how this is done?
[Edit: Adjusted the indentation for clarity]
Upvotes: 0
Views: 461
Reputation: 657
Yeah I see it's quite easy now after looking into it.
So basically he assigns the char pointer to output and runs it in a for loop. For each hexadecimal number that it hits it shifts it right i times, i starting with 7 and i > = 0
So for example
./bits 0xe7 shift 7
============<<0xe7>>============
Decimal: 231
Bits: [11100111]
==========<<Shifted>>===========
Decimal: 1
Bits: [00000001] >> 7
he then continues and & (ands) the result with 1, which in this case would return
00000001
00000001
--------
1
The drawing of the bang (!) character depends on weither the and gives us '0' or '1' for result because last but not least he adds the shifted/and result to the hex number 0x20.
0x20 being the decimal number 32, has the character representation of a white space, so if the and happens to return 0 we simply draw a white space, otherwise 1 get's added and we get the decimal number 33, which has a character representation of a bang.
Of course there are few things to note, like you both kindly pointed out there is the terminating value 0x00 and 0x01 to denote a newline.
In each row he prints 32 characters, or 4 * 8 since he's printing 8 characters for each hex value.
Thank you guys for suggesting my own solution to this since that was way more fun than just getting the answer ;)
Upvotes: 1
Reputation: 24676
One hint, think about the binary representation of the array output
. One place where this technique comes up is in the control of the bits within a hardware register as you might do in an embedded system- which is a place where C really shines.
Upvotes: 1