本章可以看作是 《Unix 环境高级编程》Ch7 的笔记。

C 程序运行的开始和结束

一个可以运行的 C 语言总要有一个 main 函数,main 函数现在的完整定义是 int main(int argc, char *argv[] ) ,现在的 C 语言已经不允许写成 void main() 的形式了,main 函数必须有返回值,如果 main 函数没有返回值,那么编译器会在最后默认加上 return 0 的语句。

C 语言从 main 函数开始运行是一个约定俗成的东西,甚至影响了后面的好多语言也是从类似名为 main 函数的入口开始运行程序。但是当内核执行 C 语言程序的时候,并不是直接调用了 main 函数,而是先通过一个特殊的启动程序 (a special start-up routine),这个特殊的启动程序将作为程序的起始地址开始运行,启动程序会从内核中获取命令行参数和环境变量值,然后去调用 main 函数。

一个进程的正常终止是有五种方式:

  1. 从 main 函数返回
  2. 调用 exit 函数。
  3. 调用 _exit 函数或者 _Exit 函数。
  4. 最后一个线程从其启动例程返回。
  5. 从最后一个线程调用 pthread_exit 。

所以,这个启动的例程实际上调用的是 exit(main(argc, argv[])) 这个函数。

退出程序有三种分别是

  1. exit()
  2. _exit()
  3. _Exit()

C 语言结束的时候,也是调用的 exit 函数,exit 函数在执行的时候,会先执行一些清理处理,并且关闭所有可能的 IO 流,对所有在缓冲的数据进行冲洗。

如果直接调用 _exit 或者 _Exit 函数,则会直接退出,进入内核。

这三个函数都有一个调用参数,称为终止状态,如果调用这些函数不带这个终止状态,或者 main 函数执行了一个没有返回值的 return 语句(这个时候相当于调用的 exit 函数没有参数),或者 main 函数没有声明返回值为整数类型,那么这个进程终止的状态就是未定义的。否则,进程的终止状态就是 0 。

一个完整的 C 语言的启动过程如图。

我们之前说过,exit 函数退出的时候,还需要进行收尾工作,那么如果我们想自定义这个收尾工作的话,可以调用 atexit () 函数,它会登记我们想要调用的收尾工作调用的函数,然后让 exit 自动进行调用。这些收尾函数可以称为 handler 。

atexit 函数原型如下,它的参数是一个函数地址,exit 调用这些函数的顺序与登记这些函数的顺序相反,可以理解为存在一个handler 函数栈,越后登记的函数越先被调用。

int atexit( void (*func) (void));

C 程序的存储空间布局

一个典型的C语言程序结构如图。

C 程序一般由几个部分组成,

  • 正文段/程序段 (text) ,就是记录了程序的二进制代码。通常是只读的,防止出现意外指令被改写。
  • 初始化数据段 (Data) 存储已经初始化的全局变量或者静态变量。
  • 未初始化数据段(BSS)保存了未初始化的静态变量,在程序家在的时候会将此段中的数据初始化为 0 。
  • 栈 保存局部变量,函数调用栈信息,程序开始时自动分配内存,结束后自动释放内存。递归函数调用的时候,会形成一个新的栈帧,函数调用不会互相影响。
  • 堆 在堆中进行动态的内存分配,需要手动分配和释放内存。

C语言程序运行时的一些细节的更多相关文章

  1. Swift和OC,是编译型语言、解释性语言、运行时语言

    首先需要明确的一点是,什么是编译型语言和解释性语言 编译型语言,就是在其执行过程中需要先将其经过编译成机器码来给计算机识别的,其执行效率就会比较高这个是显而易见的,常见比如:C.C++ 而解释型语言, ...

  2. java程序运行时内存分配详解

    java程序运行时内存分配详解 这篇文章主要介绍了java程序运行时内存分配详解 ,需要的朋友可以参考下   一. 基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个 ...

  3. Java程序运行时内存划分

    1.Java程序跨平台运行的原因 主要原因是:各种平台的JVM和字节码文件 Java源程序--具体平台的机器代码文件---被编译器翻译成平台无关的Class文件,又用特定JVM运行字节码文件,JVM在 ...

  4. 小程序运行时如何助力传统APP转型?

    小程序和H5或者RN有什么区别?优越性在哪里? 长期以来,移动互联网界一直在寻找一种既能获得Native原生的体验,又可以低门槛快速开发的技术.在这个过程中出现了很多尝试,例如React Native ...

  5. c/c++编译时,指定程序运行时查找的动态链接库路径

    http://blog.csdn.net/tsxw24/article/details/10220735 c/c++编译时,指定程序运行时查找的动态链接库路径 分类: c/c++ linux 2013 ...

  6. C# 获取程序运行时路径

    Ø  前言 开发中,很多时候都需要获取程序运行时路径,比如:反射.文件操作等..NET Framework 已经封装了这些功能,可以很方便的使用. C# 中有很多类都可以获取程序运行时路径,我们没必要 ...

  7. java程序运行时内存分配详解 (转)

    转自:http://www.tuicool.com/articles/uU77v2 一.  基本概念 每运行一个java程序会产生一个java进程,每个java进程可能包含一个或者多个线程,每一个Ja ...

  8. linux下实现在程序运行时的函数替换(热补丁)

    声明:以下的代码成果,是参考了网上的injso技术,在本文的最后会给出地址,同时非常感谢injso技术原作者的分享. 但是injso文章中的代码存在一些问题,所以后面出现的代码是经过作者修改和检测的. ...

  9. 【Visual Studio】控制台程序运行时一闪而过

    问题:写一个C#控制台程序,运行时控制台一闪而过.程序结束.无法看清控制台输出的结果. 办法: 方法一二三都有人写过百度经验了:怎么解决VS运行程序一闪而过 其实还有一种办法,就是把控制台程序改为Wi ...

随机推荐

  1. python迭代器生成器-迭代器和list区别

    迭代 生成 for循环遍历的原理 for循环遍历的原理就是迭代,in后面必须是可迭代对象 为什么要有迭代器 对于序列类型:字符串.列表.元组,我们可以使用索引的方式迭代取出其包含的元素.但对于字典.集 ...

  2. 为NLog自定义LayoutRenderer

    长话短说 前文<解剖HttpClientFactory,自由扩展HttpMessageHandler>主要想讲如何扩展HttpMessageHandler,  示例为在每个Http请求中的 ...

  3. PHP自动发红包代码示例

    <?php header('Content-type:text'); define("TOKEN", "weixin"); $wechatObj = ne ...

  4. 【灵魂拷问】你真的懂得Mysql的管理和使用吗?

    作者 | Jeskson 来源 | 达达前端小酒馆 MySQL管理,数据库管理和数据表管理,用户管理. 初始化数据库,创建数据库,查看数据库,删除数据库. 创建数据表,查看数据表,修改数据表,删除数据 ...

  5. Git的安装和使用教程详解

    ---恢复内容开始--- 本篇笔记聊聊Git的安装和使用教程 一.认 识 Git                                                            ...

  6. Vue + TypeScript 踩坑总结

    vue 和 TypeScript 结合的情况下,很多写法和我们平时的写法都不太一样,这里总结我项目开发过程中遇到的问题和问题的解决方案 有些问题可能还没解决,欢迎各位大佬给与提点. 另外,使用本文前可 ...

  7. nginx反向代理、负载均衡

    什么叫反向代理? A用户--> B(在和C同一个机房,并且有公网)--> C(不带公网的机器) 什么场景下会用到反向代理? 1.访问不带公网的内网机器 2.解决两台之间通信有障碍的问题 编 ...

  8. 浏览器url访问tomcat出现错误 java.lang.NoSuchMethodError解决方法

    一般该类错误: 找不到方法或找不到类, 都是maven pom 仓库依赖的问题,有时是 因为缺少该依赖类,可以考虑添加相关依赖: 有时因为依赖冲突, 可以到 maven 的仓库下面把 有关该类的包 全 ...

  9. SpringMVC Mock测试

    什么是mock测试? 在测试过程中,对于某些不容易构成或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,就是Mock测试. Servlet.Request.Response等Servle ...

  10. Unity3D for iOS初级教程:Part 1/3(上)

    转自:http://www.cnblogs.com/alongu3d/archive/ 如果图片看不到,请查看原文 这篇教材是来自教程团队成员 Christine Abernathy, 他是Faceb ...