1、printf和scanf缓冲区
int main()
{
printf("hello");
sleep(5);
printf("world");
exit(0);
return 0;
}
上面代码的执行情况为先睡眠5秒钟,再打印hello world
原因是C语言中的scanf gets函数将输入内容放进输入缓冲区,printf puts将输出的内容放入输出缓冲区
缓冲区再内存上,缓冲区的作用是为了提高效率。
将输出缓冲区刷新(刷到屏幕上)的条件有
(1)程序结束
(2)遇到“\n”
(3)缓冲区满(系统默认1024个字节)
(4)主动刷新 fflush(stdout);
2、exit,_exit,_EXIT函数
_exit和_Exit立即进入内核,而exit要先做一些清理工作(调用执行终止处理程序,关闭所有标准I/O流),再进入内核。三个函数所带的整形参数称为终止状态或退出状态,如果(a)调用这些函数不带参数,(b)main函数中的return 语句无返回值,(c)main函数没有声明返回类型为整形,则进程的终止状态是未定义的。main函数返回一个整形值与用该值调用exit等价。exit(0)结束进程,但是不会刷新缓冲区。
exit()函数用于在程序运行的过程中随时结束程序,exit的参数state是返回给操作系统,返回0表示程序正常结束,非0表示程序非正常结束。
3、atexit函数
atexit(void(*fun));注册一个退出函数。
exit函数运行时首先会执行由atexit()函数登记的函数,然后会做一些自身的清理工作,同时刷新所有输出流、关闭所有打开的流并且关闭通过标准I/O函数tmpfile()创建的临时文件。
一个进程最多注册32个atexit函数。先注册的后执行,像栈一样。
void fun()
{
printf("i am fun");
}
int main()
{
atexit(fun);
printf("hello\n");
sleep(5);
printf("world\n");
return 0;
}
这段程序的运行情况是打印hello睡眠5秒,打印world,打印i am fun
atexit函数是在进程结束时,当main中调用exit函数的时候,会做一些自身清理工作,同时刷新标准输出缓冲区中的内容),当执行到exit(0)时,exit会自动调用已注册过的函数,但是由于压栈过程中先进后出的原则,所以先注册的函数最后执行。如果一个函数被atexit()登记多次也会被exit()调用多次。