main函数是什么又叫什么函数

Main函数之前 v2011
我的图书馆
Main函数之前 v2011
&本帖最后由 crifan 于
16:34 编辑
Main函数之前
Author: green-waste (【声明】
此文主要是摘录和整理《程序员修养》那本书中关于运行库部分相关的内容,为了简要的总结一下main函数之前都干了啥。 【正文】
& &&&多数人接触C语言的人,对main函数,应该都比较了解了。不少人,应该是,或许以为main就是程序执行的入口,或许知道main函数不是入口,但是不知道哪里是入口,又或许知道入口,但是对于main之前发生的事情,系统做了哪些事情,不是很清楚。那么,下面这段文字,目的就是简单介绍一下,main之前到底发生了什么。在main函数中,一般来说,你可以放心去使用很多资源了,比如:申请内存,使用系统调用,触发异常,访问I/O,使用scan/printf等输入输出等等。之所以你可以放心使用这些资源,那么是因为有人帮你在main函数执行之前,就帮你准备好了这些东西供你使用。到底是谁做的?答案是,运行库。不过在介绍运行库之前,先要清楚一般程序执行的过程是怎么样的。 【程序运行步骤】一个典型的程序运行步骤大致如下:(1)操作系统在创建进程后,把控制权交到了程序的入口,这个入口往往是运行库的某个入口函数。(2)入口函数对运行库和程序运行环境进行初始化,包括堆Heap,I/O,线程。全局变量构造等等。(3)入口函数在完成初始化之后,调用main函数,正式执行程序主体部分。(4)Main函数执行完毕之后,返回到入口函数,入口函数进行清理工作,包括全局变量析构、堆销毁、关闭I/O等,然后进行系统调用结束进程。 【入口函数】
& & 从上面可以看出,其实真正所谓的程序开始部分,其实可以算是入口函数。入口函数,也叫入口点(Entry Point),是运行库的一部分,视平台不同而有不同名字。下表显示了不同平台下,对应的入口函数的相关内容:表格 1 不同平台下的入口函数相关信息平台运行库入口函数的名称说明LinuxGlibc.c__libc_start_main详情参考glibc源码中libc/csu位置的源码WindowsMSVC CRT的Crt0.cmainCRTStartup以Microsoft Visual Studio 2003为例,代码位于VC安装目录crt/src中 【__libc_start_main和mainCRTStartup】
& && & 1. __libc_start_main Glib的库源码中找到的文件是:csu\Libc-start.c对应函数代码为:STATIC int
LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
& &int argc, char *__unbounded *__unbounded ubp_av,
#ifdef LIBC_START_MAIN_AUXVEC_ARG
& &ElfW(auxv_t) *__unbounded auxvec,
& &__typeof (main) init,
& &void (*fini) (void),
& &void (*rtld_fini) (void), void *__unbounded stack_end)
#if __BOUNDED_POINTERS__
# define argv ubp_av
&&/* Result of the 'main' function.&&*/
&&__libc_multiple_libcs = &_dl_starting_up && !_dl_starting_
#ifndef SHARED
&&char *__unbounded *__unbounded ubp_ev = &ubp_av[argc + 1];
&&INIT_ARGV_and_ENVIRON;
&&/* Store the lowest stack address.&&This is done in ld.so if this is
& &&&the code for the DSO.&&*/
&&__libc_stack_end = stack_
# ifdef HAVE_AUX_VECTOR
&&/* First process the auxiliary vector since we need to find the
& &&&program header to locate an eventually present PT_TLS entry.&&*/
#&&ifndef LIBC_START_MAIN_AUXVEC_ARG
&&ElfW(auxv_t) *__
& & char *__unbounded *__unbounded evp = ubp_
& & while (*evp++ != NULL)
& & auxvec = (ElfW(auxv_t) *__unbounded)
&&_dl_aux_init (auxvec);
# ifdef DL_SYSDEP_OSCHECK
&&if (!__libc_multiple_libcs)
& && &/* This needs to run to initiliaze _dl_osversion before TLS
&&setup might check it.&&*/
& && &DL_SYSDEP_OSCHECK (__libc_fatal);
&&/* Performe IREL{,A} relocations.&&*/
&&__libc_csu_irel ();
&&/* Initialize the thread library at least a bit since the libgcc
& &&&functions are using thread functions if these are available and
& &&&we need to setup errno.&&*/
&&__pthread_initialize_minimal ();
&&/* Set up the stack checker's canary.&&*/
&&uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
# ifdef THREAD_SET_STACK_GUARD
&&THREAD_SET_STACK_GUARD (stack_chk_guard);
&&__stack_chk_guard = stack_chk_
&&/* Register the destructor of the dynamic linker if there is any.&&*/
&&if (__builtin_expect (rtld_fini != NULL, 1))
& & __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);
#ifndef SHARED
&&/* Call the initializer of the libc.&&This is only needed here if we
& &&&are compiling for the static library in which case we haven't
& &&&run the constructors in `_dl_start_user'.&&*/
&&__libc_init_first (argc, argv, __environ);
&&/* Register the destructor of the program, if any.&&*/
&&if (fini)
& & __cxa_atexit ((void (*) (void *)) fini, NULL, NULL);
&&/* Some security at this point.&&Prevent starting a SUID binary where
& &&&the standard file descriptors are not opened.&&We have to do this
& &&&only for statically linked applications since otherwise the dynamic
& &&&loader did the work already.&&*/
&&if (__builtin_expect (__libc_enable_secure, 0))
& & __libc_check_standard_fds ();
&&/* Call the initializer of the program, if any.&&*/
#ifdef SHARED
&&if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
& & GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
&&if (init)
& & (*init) (argc, argv, __environ MAIN_AUXVEC_PARAM);
#ifdef SHARED
&&/* Auditing checkpoint: we have a new object.&&*/
&&if (__builtin_expect (GLRO(dl_naudit) & 0, 0))
& && &struct audit_ifaces *afct = GLRO(dl_audit);
& && &struct link_map *head = GL(dl_ns)[LM_ID_BASE]._ns_
& && &for (unsigned int cnt = 0; cnt & GLRO(dl_naudit); ++cnt)
& &if (afct-&preinit != NULL)
& &&&afct-&preinit (&head-&l_audit[cnt].cookie);
& &afct = afct-&
#ifdef SHARED
&&if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
& & GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
#ifdef HAVE_CLEANUP_JMP_BUF
&&/* Memory for the cancellation buffer.&&*/
&&struct pthread_unwind_buf unwind_
&&int not_first_
&&not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
&&if (__builtin_expect (! not_first_call, 1))
& && &struct pthread *self = THREAD_SELF;
& && &/* Store old info.&&*/
& && &unwind_buf.priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
& && &unwind_buf.priv.data.cleanup = THREAD_GETMEM (self, cleanup);
& && &/* Store the new cleanup handler info.&&*/
& && &THREAD_SETMEM (self, cleanup_jmp_buf, &unwind_buf);
& && &/* Run the program.&&*/
& && &result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
& && &/* Remove the thread-local data.&&*/
# ifdef SHARED
& && &PTHFCT_CALL (ptr__nptl_deallocate_tsd, ());
& && &extern void __nptl_deallocate_tsd (void) __attribute ((weak));
& && &__nptl_deallocate_tsd ();
& && &/* One less thread.&&Decrement the counter.&&If it is zero we
&&terminate the entire process.&&*/
& && &result = 0;
# ifdef SHARED
& && &unsigned int *ptr = __libc_pthread_functions.ptr_
& && &PTR_DEMANGLE (ptr);
& && &extern unsigned int __nptl_nthreads __attribute ((weak));
& && &unsigned int *const ptr = &__nptl_
& && &if (! atomic_decrement_and_test (ptr))
/* Not much left to do but to exit the thread, not the process.&&*/
__exit_thread (0);
&&/* Nothing fancy, just call the function.&&*/
&&result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
&&exit (result);
2.mainCRTStartup此处安装的VS2005,对应的文件为:C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\crt0.cmainCRTStartup函数代码为: __declspec(noinline)
__tmainCRTStartup(
unsigned int osplatform = 0;
unsigned int winver = 0;
unsigned int winmajor = 0;
unsigned int winminor = 0;
unsigned int osver = 0;
int mainret=0;
OSVERSIONINFOA *
#ifdef _WINMAIN_
_TUCHAR *lpszCommandL
STARTUPINFO StartupI
Note: MSDN specifically notes that GetStartupInfo returns no error, and throws unspecified SEH if it fails, so
the very general exception handler below is appropriate
GetStartupInfo( &StartupInfo );
} __except(EXCEPTION_EXECUTE_HANDLER) {
return 255;
#endif /* _WINMAIN_ */
* Dynamically allocate the OSVERSIONINFOA buffer, so we avoid
* triggering the /GS buffer overrun detection. That can't be
* used here, since the guard cookie isn't available until we
* initialize it from here!
posvi = (OSVERSIONINFOA *)HeapAlloc(GetProcessHeap(), 0, sizeof(OSVERSIONINFOA));
if (!posvi) {
fast_error_exit(_RT_HEAP);
return 255;
* Get the full Win32 version
posvi-&dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
if ( !GetVersionExA(posvi) ) {
HeapFree(GetProcessHeap(), 0, posvi);
return 255;
osplatform = posvi-&dwPlatformId;
winmajor = posvi-&dwMajorV
winminor = posvi-&dwMinorV
* The somewhat bizarre calculations of _osver and _winver are
* required for backward compatibility (used to use GetVersion)
osver = (posvi-&dwBuildNumber) & 0x07
HeapFree(GetProcessHeap(), 0, posvi);
if ( osplatform != VER_PLATFORM_WIN32_NT )
osver |= 0x08000;
winver = (winmajor && 8) +
_set_osplatform(osplatform);
_set_winver(winver);
_set_winmajor(winmajor);
_set_winminor(winminor);
_set_osver(osver);
* Determine if this is a managed application
managedapp = check_managed_app();
if ( !_heap_init(1) ) /* initialize heap */
fast_error_exit(_RT_HEAPINIT); /* write message and die */
if( !_mtinit() ) /* initialize multi-thread */
fast_error_exit(_RT_THREAD); /* write message and die */
/* Enable buffer count checking if linking against static lib */
_CrtSetCheckCount(TRUE);
* Initialize the Runtime Checks stuff
#ifdef _RTC
_RTC_Initialize();
#endif /* _RTC */
* Guard the remainder of the initialization code and the call
* to user's main, or WinMain, function in a __try/__except
* statement.
if ( _ioinit() & 0 ) /* initialize lowio */
_amsg_exit(_RT_LOWIOINIT);
/* get wide cmd line info */
_tcmdln = (_TSCHAR *)GetCommandLineT();
/* get wide environ info */
_tenvptr = (_TSCHAR *)GetEnvironmentStringsT();
if ( _tsetargv() & 0 )
_amsg_exit(_RT_SPACEARG);
if ( _tsetenvp() & 0 )
_amsg_exit(_RT_SPACEENV);
initret = _cinit(TRUE); /* do C data initialize */
if (initret != 0)
_amsg_exit(initret);
#ifdef _WINMAIN_
lpszCommandLine = _twincmdln();
mainret = _tWinMain( (HINSTANCE)&__ImageBase,
lpszCommandLine,
StartupInfo.dwFlags & STARTF_USESHOWWINDOW
StartupInfo.wShowWindow
: SW_SHOWDEFAULT
#else /* _WINMAIN_ */
_tinitenv = _
mainret = _tmain(__argc, _targv, _tenviron);
#endif /* _WINMAIN_ */
if ( !managedapp )
exit(mainret);
__except ( _XcptFilter(GetExceptionCode(), GetExceptionInformation()) )
* Should never reach here
mainret = GetExceptionCode();
if ( !managedapp )
_exit(mainret);
_c_exit();
} /* end of try - except */
【运行库】
接下来,再简单解释解释运行库。运行库,即运行时库(Runtime Library),而C语言的运行库,即被称为C运行库(CRT,C Runtime Language)。最初看到这个缩写,我以为是CRT显示器呢,呵呵。一个C语言运行库大致包含了如下功能:(1)启动与退出:包括入口函数及入口函数所依赖的其他函数等。(2)标准函数:由C语言标准规定的C语言标准库所拥有的函数实现。(3)I/O:I/O功能的封装和实现。(4)堆:堆的封装和实现。(5)语言实现:语言中一些特殊的功能。(6)调试:实现调试功能的代码。关于每一部分的详细内容,就不多说了。 【引用】
1.《程序员的自我修养 - 链接、装载与库》 俞甲子 石凡 潘爱民 著
TA的最新馆藏[转]&
喜欢该文的人也喜欢main不是主函数吗?为什么在这里是标识符
前面的main都是主函数,main在这里却是标识符
2-1有名有姓的C那里的图片上面标着main是标识符
写下你的评论...
在C中,无论是函数名还是变量名都称作标识符(main当然是标识符了),只不过分为系统给定的标识符和用户自定义的标识符,只要明白在定义函数名或者是变量名的时候不要与系统的标识符重名就行了(当然要按照定义标识符的规矩来定义)。其实即使你定义的时候不小心重名了,编译器也会提醒你的,这不是大的问题。
写下你的评论...
Copyright (C)
All Rights Reserved | 京ICP备 号-2C语言中,文件包含命令是什么意思,还有,main是主函数的函数名是什么意思,怎么理解。
刚开始学C语言,所以有些看不懂,希望大家指点一下。C语言书中涉及数学和英文是不是比较多。或者还涉及到了哪些学科知识。
包含命令是#include,意义是在文件里包含另一个文件的内容。main是程序的入口,它本身的名字就是main。C语言涉及的英文并不是很多,函数到是多一点,想要了解函数可以看看C的函数手册。
其他答案(共3个回答)
1,看来你真是初学者,对此我的建议是,你先不用理解太多,只要知道main函数是程序入口地址,也就是说每次写程序都得有一个main(),然后多多练习程序,有些概念时间久了自然会理解。有些问题,现在无论我怎么解释,你都很难理解的。所以,别问太多,多练习就好,只是每次写程序都要有一个main(),这一点先记住就好。记住,要想学好,就得多练,多写程序,刚开始不会写,可以照抄程序,然后做少量修改,改着改着,你就明白程序怎么写了。2,关于数学相关信息A等于二乘三乘N的平方,B等于三乘N的平...在平面直角坐标系中,已知点A (a+1,...求下列函数中自变量的取值范围,(1)Y=...学会中医推拿的方法是什么?我们班有30人,有一个人回家用了3分钟,...把一个高为8厘米的圆柱,切拼成一个近似的...反比例函数y等于x分之kx大于0的图象经...你能举例说说求一组数据的平均数的方法吗?与平面x-y+2z-6=0垂直的单位向量...如图,直线y=kx+b与y=mx+n的交...直角三角函数平行线间距离直角形斜边长二重积分求r非线性电阻有,英文或是其他学科。
其实c语言,也只是一种工具,一种和计算机打交道的工具。就想英语,汉语一样。只是英语、汉语都是和人打交道的。而计算机听不懂这些,你得用他能理解的语言来和他沟通,这就是计算机语言。这里边是需要一点英文,但不多,我有一个没学过英文的同学(他主修俄语),照样程序写的很好。数学嘛,这个就得看你的应用方向了。
输入参数为空,返回参数为空。通常一个代码从main函数开始运行,即程序入口。
楼上的错了吧你在#include"graphi.h"看看现成的函数啊。
一个程序,无论复杂或简单,总体上都是一个“函数”;这个函数就称为“main 函数”,也就是“主函数”。比如有个“做菜”程序,那么“做菜”这个过程就是“主函数”。...
sfr与sfr16用于定义8051的特殊功能寄存器,其中sfr用来定义8为特殊功能寄存器,sfr16用来定义16位特殊功能寄存器。sfr P0=0x80;
答: 有人知道密乐玛游轮(Mirimar Boat Cruise)有没有从龙柏考拉园返程到市里的行程
答: 如果你理解能力强考数据库,其中比如关系数据库之类的需要去领悟如果你记忆能力强考网络,各种各样的名词,背下来就得分。还有官方指定的教材要有,上机最好做一做南开百题...
答: 新年好!首先,你必须了解计算机的组成和结构以及操作系统的运作原理,这是基础如果你想学习开发多线程、WINDOWS应用、动态链接库、WINDOWS组件的话,建议你...
大家还关注
确定举报此问题
举报原因(必选):
广告或垃圾信息
激进时政或意识形态话题
不雅词句或人身攻击
侵犯他人隐私
其它违法和不良信息
报告,这不是个问题
报告原因(必选):
这不是个问题
这个问题分类似乎错了
这个不是我熟悉的地区
相关问答:123456789101112131415君,已阅读到文档的结尾了呢~~
C复习讲稿,c语言复习,c语言复习资料,党课讲稿,郝万山伤寒论讲稿,2014年党课讲稿,小学法制副校长讲稿,宪法讲稿,百家讲坛讲稿,小学生法制教育讲稿
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口C语言中:主调函数和main函数的关系,谢谢 C语言 主函数 main 到底是什么?
你正在浏览: & >
C语言中:主调函数和main函数的关系,谢谢
C语言中:主调函数和main函数的关系,谢谢
funC 是被掉函数。funB(); 在这里,我们说 funC 是主调函数:main 函数也是可以作为【被掉函数】的,只不过这样程序一般就是死循环;/ 在这里。反过来;/ 在这里。main();}int main(){/ 在这里,我们说 funC 是主调函数在 A 函数里面调用了 B 函数,也就是说程序运行起来,main 函数是第一被调用的函数,main 是被掉函数。&#47,我们说 funB 是主调函数,funC 是被掉函数,主调函数不一定就只有 main 函数,其他函数只要在内部调用了任何函数;funC();}void funB(){{&#47,不论你要调用任何其他函数,都必须在 main 函数里面调用,那么 A 函数就是【主调函数】,这时候 main 函数就是【主调函数】。funC();}void funC(){/&#47,funA 是被掉函数。funA()。【主调函数】其实是一个【相对的概念】,它是相对于【被掉函数】来说的,我们说 funA 是主调函数,funB,我们说 main 是主调函数,funA 是被掉函数,那么它也是主调函数了。void funA(){//【注意】,B 函数式【被调函数】,因此没有正常的程序会这么写。在 C 语言里面,main 函数程序的入口;/ 在这里;/&#47。也即是说,main 函数一般作为主调函数的。接下来
只有通过大门才能进入这座房屋,即main函数是一个程序的入口;在一个程序中有很多函数,比如函数A,B,C,如果A调用了B,那么A就是B的主调函数,B调用了C那么B就是C的主调函数如果把一个程序比作是一座房屋,即,那么main函数就是这座房屋的大门
主调函数就是mian函数
断言是个宏,在stm32f10x_conf.h定义的。编译的时候编译器会把__FILE__替换成断言...
你可能感兴趣的内容?}

我要回帖

更多关于 idea main函数 快捷键 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信