main函数执行前、后再执行的代码

2024-09-08 07:58
文章标签 代码 函数 执行 main

本文主要是介绍main函数执行前、后再执行的代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、main结束 不代表整个进程结束
  (1)全局对象的构造函数会在main 函数之前执行,
          全局对象的析构函数会在main函数之后执行;
          用atexit注册的函数也会在main之后执行。
  (2)一些全局变量、对象和静态变量、对象的空间分配和赋初值就是在执行main函数之前,而main函数执行完后,还要去执行一些诸如释放空间、释放资源使用权等操作

  (3)进程启动后,要执行一些初始化代码(如设置环境变量等),然后跳转到main执行。全局对象的构造也在main之前。



C语言没有构造函数问题,所以main差不多一定是第一个被调的函数了。
C++继承了这个说法,所以编译器会在mian里加上2个函数
int main()
{
    __enter_main();//于此构造所有全局变量
    //你的代码
    __exit_main();//于此析构所有全局变量
}
当然,也可能封装成
int real_main()
{
    __before_main();
    main();
    __after_main();
}
所以,在调用你写的main里面的第一行代码前,完全可能调用其它函数。

#include <iostream>
void fn1(void)
{printf("next.\n"); 
}void fn2(void)
{printf("executed "); 
}void fn3(void)
{printf("is "); 
}void fn4(void)
{printf("This ");
} int main(void)
{// // 注册需要在 main 函数结束后执行的函数.  // 请注意它们的注册顺序和执行顺序// 在 main 函数结束后被调用,调用顺序与注册顺序相反。 先注册后执行。//atexit(fn1);atexit(fn2);atexit(fn3);atexit(fn4);// 这条输出语句具有参照性,它可不是最后一句输出. puts("This is executed first."); // EXIT_SUCCESS 代表 0,它定义在 stdlib.h 中. // 我只是顺便提一下,也许你知道,但我担心你不知道,呵呵. //return EXIT_SUCCESS;
}

关于atexit函数我的稍微补充一下,原型如下:
[cpp]  view plain copy print ?
  1. int atexit(void (*func)(void));   
   atexit 函数是标准 C 新增的。它“注册”一个函数,使这个函数将在 exit 函数被调用时或者当 mian 函数返回时被调用。当程序异常终止时(例如调用 abort 或 raise),通过它注册的函数并不会被调用。编译器必须至少允许程序员注册32个函数。如果注册成功,atexit 返回0,否则返回非零值。没有办法取消一个函数的注册。在 exit 所执行的任何标准清理操作之前,被注册的函数按照与注册顺序相反的顺序被依次调用。每个被调用的函数不接受任何参数,并且返回类型是 void。被注册的函数不应该试图引用任何存储类别为 auto 或 register 的对象(例如通过指针),除非是它自己所定义的。多次注册同一个函数将导致这个函数被多次调用。有些传统 C 编译器用 onexit 这个名称实现了像是的功能。
   atexit是注册后进先出的函数,和函数入栈出栈是一样的。
   在这里注册了四个函数,理解为入栈的顺序为fn1() -> fn2() -> fn3() -> fn4();出栈的顺序正好相反,而什么时候出栈呢?就是在调用函数结束时,准确的说应该是函数调用的最后的操作就是出栈过程。main()同样也是一个函数,在结束时,按出栈的顺序调用四个函数,即为fn4() -> fn3() -> fn2() -> fn1();
   注册这个函数的目的就是为了在函数退出时调用的,即使是main()函数也是这样的。可以在这些函数中加入一些清理工作,比如内存释放等等。



这篇关于main函数执行前、后再执行的代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147555

相关文章

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

在MySQL执行UPDATE语句时遇到的错误1175的解决方案

《在MySQL执行UPDATE语句时遇到的错误1175的解决方案》MySQL安全更新模式(SafeUpdateMode)限制了UPDATE和DELETE操作,要求使用WHERE子句时必须基于主键或索引... mysql 中遇到的 Error Code: 1175 是由于启用了 安全更新模式(Safe Upd

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav