C语言中的main函数为啥被称作程序入口

先前在学Python时,对于类前的__main__看清有过摸底,后来在学习C语言时发现实际上都以互通的。全部的顺序入口,比如main大概WINmain,在广大编程语言中都是主函数的章程面世。上面为我们整理了部分程序入口的基本概念。

 

第三,大家的次序进入到入口函数以前,是爆发了无数作业的。操作系统的布置,运转运维时库,运维时库再开端化好条件,然后运转你的入口函数,你的先后才健康的周转起来。等你的程序运维停止后,就退回到运转时库,然后再退回到操作系统,然后系统再调度其他程序执行。

 

在系统把使用权交给大家的这么些进度,就是系统布局大家程序运营的经过,约等于准备进入我们先后的入口函数main或者WinMain的长河。操作系统时刻都在运营中,除非你关机断电了。而负责管理各样程序运行的一部分就是系统的调度程序。它直接和畅行警察同样的,管理进度的周转。当你双击的exe程序时,系统会检测到您的鼠标的动作,从而进行拍卖。如若发现你双击的是某些exe,系统发现你想要执行2个程序,便会配备让您的程序执行。而那些布局的人就是系统的调度程序。调度程序分析我们的exe,获取程序的体系,然后才能领略我们先后须求什么样基础环境。那里说的功底条件,指的是,程序要运行须要的底子运行库。大家用C语言写的顺序要求C运转时库,C++的则要求C++运维时库等等,其余的主次自然也急需那么些基本库。这一个库与系统毫不相关。你在支付时,采取的支出条件和工具,都会操纵程序是如何品种,那一个与前边说的顺序的周转平台不等同。Windows程序运行的阳台环境是Windows操作系统,而以此连串中还有种种基础环境,保险这些顺序可以健康运转的。一般这么些都称呼运行时库。我们用C/C++开发的,借使没有C/C++运维时库的援救,系统就不能够起动你的主次了。

 

怎么是C运行时库?
1)C运维时库就是 C run-time library,是 C 而非 C++
语言世界的概念:取那个名字就是因为你的 C 程序运行时须求那几个库中的函数.

2)C
语言是所谓的“小内核”语言,就其语言本人来说很小(不多的要紧字,程序流程控制,数据类型等);所以,C
语言内核开发出来以往,Dennis Ritchie 和 Brian Kernighan 就用 C
本人重写了 十分之九 以上的 UNIX
系统函数,并且把里面最常用的一部分单独出来,形成头文件和对应的 LIBRAGL450Y,C
run-time library 就是那般形成的。

3)随后,随着 C 语言的风行,种种 C
编译器的生产商/个体/团体都根据老的思想意识,在差别平台上都有相对应的
Standard Library,但大多数落成都是与各类平台有关的。由于种种 C 编译器对
C 的扶助和领悟有很多争辩和神秘的出入,所以就有了 ANSI C;ANSI C
(主观意图上)详细的规定了 C
语言各种要素的有血有肉意思和编译器完成需要,引进了新的函数申明方式,同时签订了
Standard Library
的正儿八经格局。所以C运维时库由编译器生产商提供。至于由其余厂商/个人/团体提供的头文件和库函数,应当称为第贰方
C 运转库(Third party C run-time libraries)。

4)C run-time library里面含有开始化代码,还有错误处理代码(例如divide by
zero处理)。你写的顺序能够没有math库,程序依然运维,只是无法处理千头万绪的数学运算,不过假使没有了C
run-time库,main()就不会被调用,exit()也不可以被响应。因为C run-time
library包罗了C程序运维的最基本和最常用的函数。

5)到了 C++ 世界里,有其它2个概念:Standard C++
Library,它包涵了上边所说的 C run-time library 和 STL。包蕴 C run-time
library 的原故很显明,C++ 是 C 的超集,没有理由再重新来1个 C++ run-time
library. VC针对C++ 参加的Standard C++ Library首要不外乎:LIBCP.LIB,
LIBCPMT.LIB和 MSVCP奥迪Q7T.LIB

 

    上面来看1个图示。
图片 1 
   
图中突显的是五个操作系统的调度程序的示意图。大家双击了exe,系统先捕获的这么些动作,将这些请求放入调度队列,然后调度程序再调度运转。调度程序要先要依据程序的项目,来运营对应须求的运转时库,然后才进入到大家程序执行。而那运转时库,是我们程序运维起来的基本功支撑,就如须要先开辟嘴巴,才能吃饭一样。运转时库简单的话,就恍如是你这几个顺序要求的管家。它随时在关注程序的运营,假如程序崩溃卓殊,这几个运转时库会驾驭的,从而做出处理。当然,运行时库运转在系统的督查之内。运转时库有点像你的先后的二姨,同时与操作系统保持联系,算是操作系统和您程序的高中级联系人。如此来明白一下运作时库,也就简单懂了啊。为何要做运营时库,因为你程序运营时必要用到这几个中央库咯。而以此运营时库,须求由系统来运转运转。
   
总括来看,大家的次序进入到入口函数从前,是暴发了许多业务的。操作系统的安排,运营运营时库,运转时库再开首化好条件,然后运转你的入口函数,你的先后才健康的周转起来。等您的程序运维停止后,就退回到运营时库,然后再退回去操作系统,然后系统再调度其余程序执行。
    上边2个不难易行的次序,从代码上看看那些效应。大家写这一个代码如下:

void main()
{
    int i = 0;
}

   
然后再那几个唯一几句代码里打个断点。光标放在那句代码上,按F9即可。打了断点后,按F5进来调剂,调试的界面如下:
    图片 2
   
那个箭头表示,程序已经进去了我们的次第,那么大家来探望进入的长河的代码执行进度。在VS界面上找到调用哦堆栈小窗口,然后你会找到以下调用堆栈窗口:
    图片 3
   
即使您看看的不是那般的,有很多问号的,或然显示怎么不可用符号等等,在对应的这条地点,右击点击呈现或导入“符号”的菜系,然后VS自动更新符号,那样就可以彰显出那个函数分符号名了。
    堆栈的表征就是先进后出,先进的在底部,那里就是这么的。
   
执行的相继从底层到顶部,从顶部可以旁观,前边的main()表示正在执行到main函数中了。大家从最底部开端往上看。底部的两条,ntdll.dll是Windows系统的一个主干库,也是系统的宗旨成效库之一,后边的本田CR-VtlUserThreadStart表示的就是系统在起步大家的exe,并创办了2个经过主线程。然后,第一句kernel.dll那一个Curry执行了BaseThreadInitThunk执行了大家的进程的主线程的发轫化工作,包罗分配线程内存等。
   
然后基本的类别开端化工作都推行完结,然后就要开头起步大家的主线程执行了。这一个进程就是图中说的运维程序到调度程序做一些初步化工作。接下来就会去运营运维时库。在接下去的八个函数执行中,都得以看出日前ConsoleApplication3始发,那几个是我们的顺序文件名,那意味那多少个函数都是为大家先后服务的,那些都是运作在大家先后的历程空间的,其实就是大家先后所占的内存块中。mainC逍客TStartup()函数的C宝马7系T就是C
RunTime(C运行时库)的意味,那里就是C运转时库的函数了,它在备选运转main函数的实施了。可是那里才刚好运转,是在做开始化运维时环境,就是调用前面的函数__scrt_common_main()。那几个函数中做了核心的运转时环境初阶化后,又调用__scrt_common_main_seh()。这一个函数也做了一密密麻麻的开首化工作,然后调用invoke_main()函数,去调用main函数运维。
    invoke_main()函数代码如下:

static int __cdecl invoke_main() throw()
{
    return main(__argc, __argv, _get_initial_narrow_environment());
}

   
你可以看看,那么些就是3个简单的调用而已,似乎此就进去了大家的main函数的推行。而对于那个多少个函数的代码,你能够直接在调用堆栈中双击就足以看来了。
   
调用堆栈中,上3个函数是被底下那3个函数所调用的,所以那些叫做调用堆栈。
   
综上所述,你可以从上有个别讲述中感受到这么些历程,在下面的代码级别中,又再三次阐明了那么些进度,想必对此进程一定特别影响深入了。而作者辈的程序代码就是在这么些进程一呵而就后,进入到大家的入口函数开端举办的。
   
然后程序执行完成后,调用堆栈的函数依次执行完退出,最后又回去了系统的调度函数中实践别的程序。