C语言 精华小问题记录

​ 在知乎中看到一个回答,说到了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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值