Code appreciation for the international C language chaotic code competition (1)
Recently, I was reading "C expert programming", which mentioned the International C language chaotic code competition (the International obfuscated C code contest ioccc ). Ioccc has many advantages. Whether you write the code yourself or analyze the winner, you can extend your knowledge in an amazing way. There are usually 10 types of winners: "The most strange abuse of rules", "the most creative source code layout", and "The simplest single line code. The comprehensive "best mirror" award is awarded to the authors of C programs that are the most difficult to read and behave strangely (but can run. Let's take a look at and analyze the award Code submitted by David Korn of Bell Labs in 1987:
main() {printf(&unix["\021%six\012\0"], (unix)["have"] + "fun" - 0x60);}
What does this code print? (Note: it has nothing to do with "have fun ").
First, let's look at a piece of code:
#include int main() { int a[5]={1,2,3,4,5}; printf("%d\n",3[a]); return 0; }
In C language, array references can be in the form of 3 [a], which is equivalent to a [3]. Let's look at the following code:
#include int main() { int a[5]={1,2,3,4,5},i=4; printf("%d\n",3[a]); printf("%d\n",i[a]); return 0; }
This representation is also acceptable. I [a] is actually equivalent to a [4. Let's look at the following code:
#include int main() { printf("%d\n",unix); return 0; }
Why can I print it out without defining UNIX? The reason is that UNIX is defined as a macro by the compiler. Equivalent to # define UNIX 1 printed out 1. The following describes the problem.
#include int main() { printf("%c\n",(unix)["have"]); return 0; }
Here UNIX is equivalent to 1, so UNIX ["have"] is equivalent to "have" [1]. We all know that "have" is a character array. Then "have" [1] is equivalent to referencing the character with the subscript of 1 in the "have" array, which is actually ;:
#include int main() { printf("0x%x",'a'); return 0; }
The hexadecimal representation of ASC code of A is 0x61. (UNIX) ["have"] + "fun"-0x60 is equivalent to 0x61-0x60 + "fun" is equivalent to 0x01 + "fun ", it is equivalent to moving the character pointer back and pointing to "UN. The subsequent sections are explained.
#include int main() { printf(&unix["\021ix\012\0"]); return 0; }
First, remove % S. % S is actually the "UN" format just mentioned. We know that the Unix macro value is 1, so
printf(&unix["\021ix\012\0"]);
Equivalent
printf(&1["\021ix\012\0"]);
According to the Form 1 ["have"] I mentioned above, we can get the same result:
printf(&"\021ix\012\0"[1]);
This form. The difference between this reference and the above is that &. Then a character array obtains a string pointer from the element whose subscript is 1. Restoring back is equivalent
printf(&"\021%six\012\0"[1],"un");
That is to say, the first element jumps over and \ 021 jumps over. Equivalent:
printf("%six\012\0","un")
\ 012 is the carriage return in the ASC code. This string is equivalent:
printf("%six\n\0","un");
So far this problem has been solved...
Summary: This code mainly applies some knowledge such as X [a] and pointer operations to help you understand arrays and pointers!