几个玩具代码(不用main的编程)

打印编译时间

#include <stdio.h>
int main()
{
    printf("本程序的编译时间为:%s %s\n",__DATE__,__TIME__);
    //  printf("%d\n",__LINE__);
    return 0;
}

这里写图片描述
主函数main为空的情况下输出helloworld

/*********/
void main()
{
}
/*********/

//以上的main函数不能修改,/***/可随意添加代码,至少4中方法

第一种:

#include <iostream>
using namespace std;

class A
{
public:
   A()
   {
      cout<<"Hello World"<<endl;
   }
};
A a;
void main()
{

}

第二种:

#include <iostream>
using namespace std;

#define main() main(){cout<<"Hello World"<<endl;} void test()

void main()
{

}

第三种:

#include <iostream>
using namespace std;

int print();
int a=print();
int print()
{
   cout<<"Hello World"<<endl;

   return 0;
}
void main()
{

}

第四种:利用VC6修改主函数的入口

#include <stdio.h>
#pragma comment(linker,"/entry:fun")
#pragma comment(lib,"msvcrt.lib")
int fun()
{
    printf("hello world\n");
    return 0;
}

void main()
{
    ;
}

这里写图片描述

暂时只有这四种了。。。。。注明一下,第四种还可以这样玩. = =

#include <stdio.h>
#pragma comment(linker,"/entry:fun")
#pragma comment(lib,"msvcrt.lib")
void main();
int fun()
{
    printf("hello world\n");
    main();
    printf("hello world\n");
    return 0;
}

void main()
{
    printf("main start\n");
}

这里写图片描述
这样就实现用其他函数去调动去main函数了……只是玩一下而已的东西,,,说了这么多,实际上是想表达main不是真正的程序的入口。在main之前有一些函数已经执行了,它们帮你分配堆栈,初始化寄存器。在main之后也有一些函数执行了,他们帮你做收尾工作。。。
好吧,抽象的话都是没人鸟的。上一个Demo吧 - -!

#include <stdio.h>
void main()//VC下会崩溃!!VS不会
{
    int x = 0;
    scanf("%f",&x);
}

这个代码应该能看懂吧,但是你故意用浮点数格式去进行输入。那么命运只有一个就是崩溃,上图….
几个玩具代码(不用main的编程)_第1张图片
但是如果你这样

#include <stdio.h>
void main()
{
    float a = 1.0;
    int x = 0;
    scanf("%f",&x);
}

这里写图片描述
看到了吧,能够成功执行,并且没有崩溃。
那么为什么呢???
加入了一个看似没什么影响的float a = 1.0;对编译器产生了什么样的影响?
= =!一般来说吧,当编译器见到了有float a = 1.0;这样子明显用过浮点数的痕迹,就会主动在main函数之前初始化浮点寄存器。这是第一点。然后还有一点,这是一条规则,凡是使用没有初始化的浮点寄存器,那么进程就只有崩溃的命运。
就是这两条,构成了程序崩溃的条件,呃,要说明一点,在VS下,已经成功修复了这个BUG。现在已经不管什么用了没有浮点数的痕迹,一上来就初始化浮点数寄存器了。。
说了这么多,只说了一点,main之前有函数执行,main函数之后也有函数执行。。。。

再给一个玩具代码,可以跳过n个函数

#include <iostream>
using namespace std;
void Show()
{
    cout<<"hello world"<<endl;
}
void fun()
{
    void *p = NULL;
    p = &p+2;
    *(int*)p += 5;
}
void main()
{
    Show();
    fun();//执行一个fun函数让跳过后面的Show函数
    Show();
    Show();
    Show();
}

这里写图片描述
这个用到了越界访问函数返回地址的原理。给出函数栈帧上的内存分布
几个玩具代码(不用main的编程)_第2张图片

你可能感兴趣的:(编程,main,玩具,函数栈帧)