• 最短的可通过编译的C语言程序


    要求:写一个最短的,能通过编译的C语言程序,但不要求能正确运行。

    一般人首先想到的是除0。即

    int main()
    {
    return 1/0;
    }

    除0会引发SIGFPE信号(浮点异常)。

    我们也可以删掉return,但是这样做的话编译器会把这句没有值的语句优化掉。那么我们就改成赋值语句:

    i;
    int main()
    {
    i = 1/0;
    }

    在C89标准里,声明一个整形变量可以省略int。因此我们还可以把main函数的int类型声明也省略掉,变成

    i;
    main()
    {
    i = 1/0;
    }

    不计任何空格,这段程序只有16个字符,可以说是非常短了。但是,我们还可以进一步缩短它。

    当C程序在编译的时候,编译器会产生一个或更多对象文件,文件里有对于用到的库和全程对象(函数和变量)的符号索引。然后这些对象文件会进行链接,这是符号索引被地址所代替,就产生了一个可执行文件。

    编译器在一个对象文件里提供了一个调用main函数的入口点。调用main函数,意味着我们试图执行存储在main函数链接的位置所对应的地址里的指令。

    有趣的是,链接器对于不同对象的类型是没有概念的,它只知道它们的地址。所以,如果我们用一个常规的全程变量替换main函数,编译器会高兴地build对象文件,因为它不关心main的类型是什么;链接器也会高兴地链接它,因为它只关心main函数对应的地址。

    所以,考虑这个C程序:

    int main=0;

    这个程序会试图按函数的方式去执行main,但是这样不会奏效,因为编译器把它放到了不可访问的地址上,所以变量main实际上可以初始化为任何值。

    继续省略int类型声明,我们得到:

    main=0;

    而事实上,main在这里是个全局变量,而C语言中的全局变量都会隐式地初始化为0,因此上述语句就等价于

    main;

    好了,这个程序可以编译通过!虽然执行的时候一定会触发SIGSEGV信号,产生Segment fault。但这已经满足了我们一开始给出的要求了(能编译通过但不一定正确运行的最短C语言程序)。

  • 相关阅读:
    JAVA中的流-简介(二)
    JAVA中的流-简介(一)
    Java中内部类简介
    应用小练习-自定义栈
    集合知识点(二)
    集合知识点(一)
    JAVA中的正则表达式简介
    从头文件中学习sfr和sbit
    PCB中实现元器件旋转一个角度放置
    DXP中插入LOGO字体方法(2)
  • 原文地址:https://www.cnblogs.com/ryuasuka/p/4341094.html
Copyright © 2020-2023  润新知