一、main函数。
main函数的原型如下。argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组。
int main(int argc, char *argv[])
当内核执行C程序时(使用一个exec函数),在调用main前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址,这是由连接编辑器设置的,而连接编辑器则由C编译器调用。启动例程从内核取得命令行参数和环境变量,然后为调用main函数做好安排。
启动例程使得main返回后立即调用exit函数。例如:
exit(main(argc, argv));
二、进程终止。
有8种方式使进程终止。
1、退出函数。
3个函数用于正常终止一个程序:_exit和_Exit立即进入内核,exit先执行一些清理工作然后返回内核。exit总是执行一个标准I/O库的清理关闭操作:对于所有打开流调用fclose函数。
main函数返回一个整型值与该值调用exit是等价的。
exit(0); return (0); //两条语句等价
2、函数atexit。
一个进程可登记至多32个函数,这些函数由exit自动调用。称这些函数为终止处理函数,并调用atexit函数来登记这些函数。exit调用这些函数的顺序与它们登记时候的顺序相反。同一函数如若登记多次,也会被调用多次。exit首先调用各终止处理程序,然后关闭(通过fclose)所有打开流。
内核使用程序执行的唯一方式是调用一个exec函数。进程自愿终止的唯一方式是显示或隐式地(通过调用exit)调用_exit或_Exit。进程也可非自愿地由一个信号使其终止。
三、命令行参数。
当执行一个程序时,调用exec的进程可将命令行参数传递给该新程序。注意:argv[argc]是一个空指针。
1 #include <stdio.h> 2 3 int main(int argc, char *argv[]) 4 { 5 int i; 6 for (i = 0; argv[i] != NULL; i++) 7 { 8 printf("argv[%d]: %s\n", i, argv[i]); 9 } 10 11 return 0; 12 }
四、环境表。
每个程序都接收到一张环境表。与参数表一样,环境表也是一个字符指针数组,其中每个指针包含一个以null结束的C风格字符串地址。全局变量environ则包含了该指针数组的地址。
称environ为环境指针,指针数组为环境表,其中各指针指向的字符串为环境字符串。通常用getenv和putenv函数来访问特定的环境变量,而不是用environ,但如果要查看整个环境,必须使用environ指针。
五、C程序的存储空间布局。
六、共享库。
共享库使得可执行文件中不再需要包含公用的库函数,而只需在所有进程都可引用的存储区中保存这种库的一个副本。程序第一次执行或者第一次调用某个库函数时,用动态链接方法将程序与共享库函数相链接。这减少了每个可执行文件的长度,但增加了一些运行时间开销。
七、函数setjmp和longjmp。
在C中,goto语句是不能跨越函数的,执行这种类型跳转功能的是函数setjmp和longjmp。这两个函数对于处理发生在很深层嵌套函数调用中的出错情况是非常有用的。
八、函数getrlimit和setrlimit。
每个进程都有一组资源限制,其中一些可以用getrlimit和setrlimit函数查询和更改。进程的资源限制通常是在系统初始化时由0进程建立的,然后由后续进程继承。每种实现都可以用自己的方法对资源限制做出调整。