在知乎中看到一个回答,说到了1987年国际C语言混乱代码大赛获奖的一行代码,代码只有一行,却穷尽了C中的精华。
main() { printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
看了一下,记录一下,防止以后忘记了,以下是根据原文章的描述加上自己的理解,以自己容易懂的方式重写了一下。此处为斜杠\
转义字符的用处参考链接。
#define unix 1
int main()
{
/* unix被编译器内定为一个宏
* 相当于#define unix 1 */
printf("unix=%d\n", unix); /* =1 */
/* 以下为前半部分 = "ix"
* ----------------------------------------------------------------------------
* 首先说一个知识点,在c语言中,"abcde"是一个字符串,同时可以被近似理解为字符数组
* 而"abcde"和&"abcde"其实都是表示这个字符串的地址
* 我自己是这么理解的,char *a = "abcde";
* "abcde"就相当于a,而a放的就是字符串"abcde"的首地址;&"abcde"就更不用说了,直接取首地址;
* 其次,在C语言中,x[1] = 1[x], 即&"abcde"[1] == &(1)["abcde"]
* 如下:
* ----------------------------------------------------------------------------
*/
/* 下面两个都输出"bcde", 因为指针都是从'b'开始;
* 也可以用%x打地址出来,两者是一致的,这里加一句,在C语言中,"abcde"被看作字符串常量,字符串常量被存储在静态存储区,因为字符串常量很少需要修改,放在静态内存区会提高效率,所以字符串常量不能被修改而且在程序运行期间地址是不会改变的。
*/
printf("%s %x\n", "abcde" + 1, "abcde" + 1);
printf("%s %x\n", &"abcde"[1], &"abcde"[1]);
printf("%s %x\n", &(1)["abcde"], &(1)["abcde"]);
/* 到这里,前半部分可以看作这样 &"\021%six\012\0"[1]
* 那么在这里就需要再说一个知识点了,之前不知道,查了文章才知道,是上述斜杠的转义字符的用处
* 参考上述转义字符作用,\a,表示八进制的a,因平常八进制在前头加0,所以此处\021 \012加0只是为了更好的区分是八进制
* 即 \021 == 021 == 0x11,算字符串中的第一位,取[1]即跳过
* \012 == 012 == 0x0a,及\n(LF),换行符
* \0是空字符,表示这个字符串到此结束
*/
/*
* 所以,前半部分已经说明完成,即 &"\021%six\012\0"[1] == &"%six\n\0"
* printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60); == printf("%six\n\0"],(unix)["have"]+"fun"-0x60);
*/
printf("%s\n",&"\021%six\012\0"[1]); //输出%six + 换行
printf(&"\021%six\012\0"[1],"jzy"); // 输出jzyix + 换行
/* 以下为后半部分 = "un"
* --------------------------------------------------------------------------------------
* 上面也说过 (unix)["have"] == (1)["have"] == "have"[1] == 'a' == 97 == 0x61
* 所以(unix)["have"]+"fun"-0x60 == "fun" + 'a' - 0x60 == "fun" + 0x61 - 0x60 == "fun" + 1
* 即"fun" + 1,字符串"fun"指向"un"
* --------------------------------------------------------------------------------------
*/
/*
* 至此,问题解决!!!输出"unix"
*/
printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);
return 0;
}
对了,还看见一个比较好玩的恶搞
#define return return
#define true false
#define printf print
#define int unsigned short