首页 > 其他分享 >对于C语言,什么算作normal exit

对于C语言,什么算作normal exit

时间:2024-10-23 11:43:50浏览次数:6  
标签:调用 函数 normal 程序 C语言 atexit cleanup exit

在C语言中,atexit() 函数用于注册程序正常退出时要执行的清理函数。这个函数会在程序 正常退出 时自动调用,以执行任何需要在程序结束时清理的操作,例如关闭文件、释放动态分配的内存等。

要理解 atexit() 函数的行为,首先需要明确什么算作 **"normal exit"**(正常退出)。

什么是 "normal exit"(正常退出)

在C语言中,程序的正常退出指的是程序通过以下方式之一结束运行,而非由于信号中断、未捕获的异常或调用 abort() 等导致的异常终止。

1. 调用 exit() 函数

exit() 是C语言标准库中的一个函数,用来终止程序。无论在何处调用 exit(),它都会导致程序结束,并执行已注册的 atexit() 函数。

#include <stdio.h>
#include <stdlib.h>

void cleanup() {
    printf("Cleanup function called.\n");
}

int main() {
    atexit(cleanup);  // 注册 cleanup 函数
    printf("Exiting the program...\n");
    exit(0);  // 正常退出,调用 exit()
}

输出:

Exiting the program...
Cleanup function called.

2. main函数通过 return 退出

main() 函数执行完毕并通过 return 语句返回时,也被视为程序的正常退出。这种情况下,返回的值会作为程序的退出状态码,而注册的 atexit() 函数同样会被调用。

#include <stdio.h>
#include <stdlib.h>

void cleanup() {
    printf("Cleanup function called.\n");
}

int main() {
    atexit(cleanup);  // 注册 cleanup 函数
    printf("Returning from main...\n");
    return 0;  // 正常退出,main函数返回
}

输出:

Returning from main...
Cleanup function called.

3. 调用 _Exit()quick_exit()(不调用 atexit() 注册的函数)

  • _Exit()quick_exit() 也可以终止程序,但它们不会调用 atexit() 注册的函数。这些函数直接退出程序,用于特殊场景。
#include <stdio.h>
#include <stdlib.h>

void cleanup() {
    printf("Cleanup function called.\n");
}

int main() {
    atexit(cleanup);  // 注册 cleanup 函数
    printf("Using _Exit...\n");
    _Exit(0);  // 正常退出,但不调用已注册的 atexit() 函数
}

输出:

Using _Exit...

什么不是 "normal exit"(非正常退出)

以下几种情况不算作程序的正常退出,atexit() 注册的函数不会被执行:

1. 调用 abort()

abort() 函数会使程序立即终止,而不会执行任何清理操作,也不会调用 atexit() 注册的函数。abort() 通常用于程序遇到严重错误,需要立即停止时。

#include <stdio.h>
#include <stdlib.h>

void cleanup() {
    printf("Cleanup function called.\n");
}

int main() {
    atexit(cleanup);  // 注册 cleanup 函数
    printf("Aborting the program...\n");
    abort();  // 非正常退出,不调用 atexit 函数
}

输出:

Aborting the program...

2. 程序崩溃(例如:段错误,SIGSEGV)

如果程序在运行过程中因段错误(segmentation fault)或其他严重错误(例如除零错误、非法指令等)而崩溃,atexit() 注册的函数不会被调用。

总结

C语言中的 "normal exit" 指的是程序通过 returnexit() 正常结束的情况。此时,atexit() 注册的函数会被调用。如果程序因调用 abort() 或发生未捕获的异常(如信号中断、段错误等)导致异常终止,则不算作正常退出,atexit() 函数不会被执行。

  • 正常退出:

    • return 结束 main() 函数
    • exit() 函数
    • 调用 quick_exit()(不会调用 atexit() 函数,但这是正常的快速退出)
  • 非正常退出:

    • abort()
    • 程序崩溃(如段错误等异常情况)

通过这些方式了解程序的退出状态并使用 atexit() 函数进行清理,可以确保资源在程序退出时得到适当释放。

标签:调用,函数,normal,程序,C语言,atexit,cleanup,exit
From: https://www.cnblogs.com/AI-aidushu/p/18496057

相关文章

  • c语言基础程序——经典100道实例。
    c语言基础程序——经典100道实例001,组无重复数字的数002,企业发放的奖金根据利润提成003,完全平方数004,判断当天是这一年的第几天005,三个数由小到大输出006,输出字母C图案007,特殊图案008,9*9乘法表009,国际象棋棋盘010,打印笑脸011,兔子生崽012,101到200的素数013,水仙花数014,分......
  • 关于我、重生到500年前凭借C语言改变世界科技vlog.8——函数递归
    文章目录1.递归的介绍2.递归的限制条件3.递归实战应用3.1求n的阶乘3.2顺序打印一个整数的每一位4.递归与迭代5.递归经典问题的拓展希望读者们多多三连支持小编会继续更新你们的鼓励就是我前进的动力!1.递归的介绍在vlog.2的printf函数的返回值举例中,我们使......
  • 实验三 C语言函数应用编程
    任务一#include<stdio.h>charscore_to_grade(intscore);//函数声明intmain(){intscore;chargrade;while(scanf("%d",&score)!=EOF){grade=score_to_grade(score);//函数调用printf("分数:%d,等级:%c\n......
  • 【趣学C语言和数据结构100例】
    #1024程序员节|征文#【趣学C语言和数据结构100例】问题描述56.设将n(n>1)个整数存放到区带头结点处单链表乚中,设计算法将L中保存的序列循环石移k(0<k<n)个位置。例如,若k=1,则将链表(0,1,2,3}变为{3,0,1,2}57.设有一个带头结点的非循环双链表L,其每个结点中除有pre、da......
  • 数据结构 链表 C语言
    数据结构第二章的链表//线性表的链式存储#include<stdlib.h>#include<stdio.h>typedefintElemType;typedefstructnode{ElemTypedata;structnode*next;}Node,*LinkList;//初始化空的单链表voidInitList(LinkList*L){*L=(LinkLis......
  • 奇偶序号分割单链表(C语言)
    算法思想:要想将单链表L按照奇偶序号分割为两个单链表A(奇),B(偶),我们便可以定义一个变量来记录当前遍历的结点序号的奇偶,两个指针ra,rb,ra负责将奇数位置结点赋到A中,rb同理核心代码:voiddevide(LinkListL,LinkListA,LinkListB){intindex=1;LNode*p=L->next;......
  • C语言学习第9天
    目录字符数组概念定义和初始化定义:初始化方式:二维字符数组字符串操作函数头文件:#include函数名:strlen(s)sizeof()和strlen()的区别函数名:strcmp(s1,s2)函数名:strcpy(s1,s2)函数名:strcat(s1,s2)函数名:void*memset(void*s,intc,size_tn);字符串输入gets()......
  • C语言中的初始化是什么意思
    在C语言中,初始化是指在定义变量时为其赋予初值的过程。通过初始化,可以确保变量在使用之前具有已知的初始值,避免了未初始化变量的不确定行为。初始化可以在变量定义时直接赋值,也可以通过赋予默认值或调用特定的初始化函数来完成。C语言中的初始化在C语言中,初始化是指在定义变......
  • C语言使用指针作为函数参数,并利用函数嵌套求输入三个整数,将它们按大到小的顺序输出。(
    输入三个整数,要求从大到小的顺序向他们输出,用函数实现。   本代码使用到了指针和函数嵌套。   调用指针做函数ex,并嵌套调用指针函数exx在函数ex中。(代码在下面哦!)一、关于函数 ex  1. 这个函数接受三个指针参数 int*p1 、 int*p2 和 int*p3 ,分别指......
  • C语言中如何实现链表
    文章开头:在C语言中,实现链表主要涉及以下几个步骤:定义链表的结点、创建链表、添加链表结点、删除链表结点、查找链表结点、打印链表和释放整个链表。我们以一个单链表为例,每一个结点包括两部分:一部分是数据域,存放元素的值;另一部分是指针域,存放下一个结点的地址。创建链表首先需要......