您的位置:首页 > 编程语言

main主函数执行完毕后,是否可能会再执行一段代码?

2010-03-18 11:20 393 查看

main主函数执行完毕后,是否可能会再执行一段代码?

先看代码,代码为王!

#include <stdlib.h>
#include <stdio.h>

int fn1(void), fn2(void), fn3(void), fn4 (void);

void main( void )
{
_onexit( fn1 );
_onexit( fn2 );
_onexit( fn3 );
_onexit( fn4 );
printf( "This is executed first./n" );
}

int fn1()
{
printf( "next./n" );
return 0;
}

int fn2()
{
printf( "executed " );
return 0;
}

int fn3()
{
printf( "is " );
return 0;
}

int fn4()
{
printf( "This " );
return 0;
}

Output :

This is executed first.
This is executed next.

**********************************************************************************

crt会执行另一些代码,进行处理工作。
如果你需要加入一段在main退出后执行的代码,可以使用atexit()函数,注册一个函数。
语法:
#include <stdlib.h>
int atexit(void (*function")(void));
#include <stdlib.h>
#include <stdio.h>

void fn1( void ), fn2( void ), fn3( void ), fn4( void );

int main( void )
{
atexit( fn1 );
atexit( fn2 );
atexit( fn3 );
atexit( fn4 );
printf( "This is executed first./n" );
}

void fn1()
{
printf( "next./n" );
}

void fn2()
{
printf( "executed " );
}

void fn3()
{
printf( "is " );
}

void fn4()
{
printf( "This " );
}

*********************************************************************************

其实main是在

mainCRTStartup中被调用的
在main之前会调用一系列初始化函数来初始化这个进程
而在main之后会调用exit(int)来进行进程的清理工作
#ifdef WPRFLAG
__winitenv = _wenviron;
mainret = wmain(__argc, __wargv, _wenviron);
#else /* WPRFLAG */
__initenv = _environ;
mainret = main(__argc, __argv, _environ);
#endif /* WPRFLAG */

#endif /* _WINMAIN_ */
exit(mainret);
楼上是说onexit是在main()之前, 来看看代码便知

exit的代码
void __cdecl exit ( int code )
{
doexit(code, 0, 0); /* full term, kill process */
}

doexit的代码
static void __cdecl doexit (int code, int quick, int retcaller)
{
#ifdef _DEBUG
static int fExit = 0;
#endif /* _DEBUG */

#ifdef _MT
_lockexit(); /* assure only 1 thread in exit path */
#endif /*_MT */

if (_C_Exit_Done == TRUE) /* if doexit() is being called recursively */
TerminateProcess(GetCurrentProcess(),code); /* terminate with extreme prejudice */
_C_Termination_Done = TRUE;

/* save callable exit flag (for use by terminators) */
_exitflag = (char) retcaller; /* 0 = term, !0 = callable exit */

if (!quick) {

/*
* do _onexit/atexit() terminators
* (if there are any)
*
* These terminators MUST be executed in reverse order (LIFO)!
*
* NOTE:
* This code assumes that __onexitbegin points
* to the first valid onexit() entry and that
* __onexitend points past the last valid entry.
* If __onexitbegin == __onexitend, the table
* is empty and there are no routines to call.
*/

if (__onexitbegin) {
_PVFV * pfend = __onexitend;

while ( --pfend >= __onexitbegin )
/*
* if current table entry is non-NULL,
* call thru it.
*/
if ( *pfend != NULL )
(**pfend)(); // 在这里循环调用onexit
}

/*
* do pre-terminators
*/
_initterm(__xp_a, __xp_z);
}

/ *
* do terminators
*/
_initterm(__xt_a, __xt_z);

#ifndef CRTDLL
#ifdef _DEBUG
/* Dump all memory leaks */
if (!fExit && _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_LEAK_CHECK_DF)
{
fExit = 1;
_CrtDumpMemoryLeaks();
}
#endif /* _DEBUG */
#endif /* CRTDLL */

/* return to OS or to caller */

if (retcaller) {
#ifdef _MT
_unlockexit(); /* unlock the exit code path */
#endif /* _MT */
return;
}

_C_Exit_Done = TRUE;

ExitProcess(code);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: