《C和C++程序员面试秘笈》——1.12 C++中main函数执行完后还执行其他语句吗

简介:

本节书摘来自异步社区出版社《C和C++程序员面试秘笈》一书中的第1章,第1.12节,作者: 董山海,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.12 C++中main函数执行完后还执行其他语句吗

C和C++程序员面试秘笈
考点: atexit()函数的使用

出现频率:

【解析】

很多时候,我们需要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有很多种,例如main()函数运行结束,在程序的某个地方用exit()结束程序,用户通过Ctrl+C等操作发信号来终止程序,等等,因此需要有一种与程序退出方式无关的方法来进行程序退出时的必要处理。方法就是用atexit()函数来注册程序正常终止时要被调用的函数。

atexit()函数的参数是一个函数指针,函数指针指向一个没有参数也没有返回值的函数。atexit()的函数原型是:

  int atexit (void (*)(void));
在一个程序中最多可以用atexit()注册32个处理函数,这些处理函数的调用顺序与其注册的顺序相反,即最先注册的最后调用,最后注册的最先调用。请看下面的程序代码。

  #include<stdlib.h>           //使用atexit()函数必须包含头文件stdlib.h
  #include<stdio.h>
  void fn1(void);
  void fn2(void);
  int main(void)
  {
    atexit(fn1);      //使用atexit注册fn1()函数
    atexit(fn2);      //使用atexit注册fn2()函数
    printf("main exit...\n");
    return 0;
  }
  void fn1()
  {
    printf("calling fn1()...\n");   //fn1()函数打印内容
  }
  void fn2()
  {
    printf("calling fn2()...\n");    //fn2()函数打印内容
  }```
上面的程序代码在main函数中调用atexit()函数依次注册了fn1()和fn2()函数。运行这个程序,我们可以得到下面的输出。

main exit…
calling fn1()…
calling fn2()…`
在这里,fn2()与fn1()在main()函数结束后被依次调用,并且它们被调用的顺序与它们在main()函数被注册的顺序相反。

【答案】

可以用 atexit()函数来注册程序正常终止时要被调用的函数,并且在 main()函数结束时,调用这些函数的顺序与注册它们的顺序相反

相关文章
|
14天前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
|
3月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
207 6
|
8月前
|
IDE Java 程序员
C++ 程序员的 Java 指南
一个 C++ 程序员自己总结的 Java 学习中应该注意的点。
70 5
|
8月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
8月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
285 6
|
8月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
100 0
C++ 多线程之线程管理函数
|
8月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
1398 1
|
8月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
138 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
4月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
14天前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。