文章目录
- 一,main函数
- 二,exit函数
- 1,exit函数
- 2,atexit()函数
- 2.1 atexit函数的简介
- 2.2 atexit注册的函数一定会被调用吗
- 2.2.1 正常退出测试
- 2.2.2 异常退出测试
一,main函数
一个C程序至少包含一个函数,这个函数就是main()
函数,它是程序的入口点。
main()
负责调用其他函数,完成程序的主要任务。
#include <stdio.h>int main() {printf("Hello, World!\n");return 0; // 程序正常结束
}
main()
函数的声明和普通函数并无区别,也包含函数头和函数体,函数头包含返回值类型、函数名称、参数列表,函数体中包含return
语句。
正常情况下,如果main()
里面省略return语句,编译器不会警告或者报错,相当于编译器会自动加上return语句,可以认为main()
的默认返回值为0
。所以,也可以写成下面这样。
#include <stdio.h>int main() {printf("Hello, World!\n");// 省略return 0; 程序正常结束
}
二,exit函数
1,exit函数
exit()
exit()函数的作用是终止整个程序,原型定义在头文件stdlib.h
里面,引入头文件后,我们可以直接在其他函数中使用。
exit()
可以起到return的作用,向函数外部返回一个值,返回值是传递给exit()
的参数。
exit()
的参数通常是两个常量:
- ①
EXIT_SUCCESS
(相当于 0)表示程序运行成功 - ②
EXIT_FAILURE
(相当于 1)表示程序异常中止。
这两个常量的定义包含在stdlib.h里面。
// 程序运行成功
// 等同于 exit(0);
exit(EXIT_SUCCESS);// 程序异常中止
// 等同于 exit(1);
exit(EXIT_FAILURE);
在main()函数里面,exit()等同于使用return语句。
#include <stdio.h>int main() {printf("Hello, World!\n");// 等同于return 0;exit(EXIT_SUCCESS);
}
其他函数使用exit(),就是终止整个程序的运行,没有其他作用。
#include <stdio.h>
#include <stdlib.h>int plus1(int num){exit(0);
}int main()
{printf("Hello World");int num = plus1(0);printf("num=%d",num);
}
如上代码,main
函数中调用plus1()
,plus1
中调用了exit
函数,执行exit
函数后,整个程序就结束,不会再执行main
函数的最后一行代码。
也即是说,我们在普通函数中调用exit
函数时传递参数,是没有什么意义的。
2,atexit()函数
2.1 atexit函数的简介
C 语言还有一个atexit()
函数,用来告知编译器在exit()
执行之前,执行一个指定的函数,这个程序可以称之为终止处理程序
,通常用来执行程序结束前的资源回收工作,比如释放内存、释放数据库连接等等,或者程序异常退出前打印异常信息。
该函数的原型定义在头文件stdlib.h。
int atexit(void (*func)(void));
注意,atexit()
的参数是一个函数指针,且这个指针指向的函数必须满足如下两个条件:
- 不接受任何参数。
- 不能有返回值。
void releaseSomething(void) {printf("releaseMemory\n");printf("releaseDBLink\n");
}
atexit(releaseSomething);
exit(EXIT_SUCCESS);
上面示例中,exit()
执行时,会先调用atexit()
函数注册的releaseSomething()
函数,之后终止程序。
可以通过atexit
注册多个终止处理程序
,同一个函数若注册多次,那它也会被调用多次。
按 POSIX.1-2001
规定,至少可以注册 32 个终止处理程序,若想查看实际可以注册多少个终止处理程序,可以通过调用 sysconf()函数获得。
2.2 atexit注册的函数一定会被调用吗
如果程序异常退出,atexit注册的函数不一定会被调用。
以下5种程序终止方式会调用atexit
注册的函数。
-
① 从main返回
-
② 调用exit函数
-
③调用 _exit 或 _Exit
-
④最后一个线程从其启动例程返回
-
⑤最后一个线程调用pthread_exit
下面三种异常终止的情况不会调用atexit
注册的函数:
- ① 调用 abort
- ② 接到一个信号并终止
- ③ 最后一个线程对取消请求做出响应
2.2.1 正常退出测试
测试代码:
#include <stdio.h>
#include <stdlib.h>void fn1(void);
int main(void) {printf("main begain!\n");atexit(fn1);printf("main exit!\n");return 0;
}void fn1() {printf("fn1 exit!\n");
}
结果显示,程序退出前执行了atexit
注册的函数。
2.2.2 异常退出测试
测试代码:
#include <stdio.h>
#include <stdlib.h>void fn1(void);
int main(void) {printf("main begain!\n");atexit(fn1);// 发出中断信号abort();printf("main exit!\n");return 0;
}void fn1() {printf("fn1 exit!\n");
}
结果显示,程序终止前没有执行atexit
注册的函数。