一、main()函數
1.函數原型int main(int argc, char *argv[])
2.參數:argc:命令行參數的數目;argv[]:指向參數的各個指針構成的數組
二、進程終止
1.有8種進程終止方式,5種正常終止,3種異常終止
(1)正常:
A.從main()函數返回
B.調用exit:先執行清理處理(標準I/O庫的清理關閉,對所有打開流調用fclose()),後返回內核
<stdlib.h>: void exit(int status);
C.調用_exit/_Exit:立即進入內核
<stdlib.h>: void _Exit(int status)
<unistd.h>: void _exit(int status)
D.最後一個線程從其啓動歷程返回
E.從最後一個線程調用pthread_exit
(2)異常:
A.調用abort
B.接到一個信號
C.最後一個線程對取消請求做出響應
2.退出函數:
(1)main()返回一個整型值==用該值調用exit();exit(0) == return 0;
(2)終止狀態:exit status;shell命令echo $?輸出終止狀態
A.未知:調用返回函數不帶終止狀態;main()執行了無返回值的return語句;main()未聲明返回類型爲整型
B.爲0:main()返回類型爲int,並且main()返回
3.atexit():登記終止處理程序(exit()自動調用)
(1)header: <stdlib.h>
(2)int atexit(void (*func) (void));
(3)parameter: 函數地址
(4)成功返回0,不成功返回非0
(5)exit()調用這些函數順序與他們登記順序相反,多次登記多次調用
(6)內核使程序運行的唯一方法:調用exec();進程自願終止唯一方法:顯式/隱式(調用exit())的調用_exit()/_Exit()
三、命令行參數
1.argv[argc]要求爲空指針
四、環境表
1.對於函數static和extern的區別:static使得函數旨在本文件內部有效,對其他文件不可見,靜態函數;extern表示函數爲外部函數,可供其他文件調用,使用其他文件中定義的外部函數,使用extern聲明即可
2.環境表:字符串指針數組,每個指針包含一個以null結尾的c字符串的地址
3.環境指針:extern char **environ,包含了環境表的地址
4.ISO C規定main()只能有兩個參數,POSIX.1規定應使用environ代替環境表地址
五、C程序的存儲空間佈局
1.c程序組成部分:
(1)正文段:右cpu執行的機器指令部分,可共享,只讀
(2)初始化數據段:包含了程序中需要明確賦初值的變量(任何函數之外的聲明)
(3)未初始化的數據段(bss):程序開始執行前,內核將此段的數據初始化爲0/空指針
(4)棧:自動變量以及每次函數調用時所需保存的信息;棧從高地址向低地址方向增長
(5)堆:動態存儲分配(位於bss和棧之間)
2.存放在磁盤程序文件中的:正文段,初始化數據段
3.Linux-size命令報告正文段、數據段、bss段長度
六、共享庫
1.使得可執行文件不再需要包含公用的庫函數,只需在所有進程都可引用的存儲區中保存這種庫例程的一個副本
2.程序第一次執行/第一次調用某個庫函數,用動態鏈接的方法將程序與共享庫函數相鏈接
3.優點:減少了可執行文件的長度;可以用庫函數的新版本代替老版本而無需對使用該庫的程序重新連接編輯(參數數目和類型)
七、存儲空間分配
1.ISO C說明了3個用來動態分配存儲空間的函數:<stdlib.h>
(1)malloc():分配指定字節的存儲區,初始值不確定
void *malloc(size_t size);
(2)calloc():爲指定數量、長度的對象分配存儲空間,每一位都初始化爲0
void *calloc(size_t nobj, size_t size);
(3)realloc():增加/減少之前分配區的長度
void *realloc(void *ptr, size_t newsize);
void free(void *ptr);
(4)返回值:成功:非空指針;失敗:NULL
2.替代的存儲空間分配程序:libmalloc, vmalloc, quick-fit, jemalloc, TCMalloc, alloca
(1)alloca():在當前函數的棧幀上分配存儲空間,而不在堆中
A.優點:函數返回,自動釋放它使用的棧幀
B.缺點:增加了棧幀的長度
八、環境變量(name = value)
1.char *getenv(const char *name); 取環境變量的值
(1)頭文件:<stdlib.h>
2.ISO C 沒有定義任何環境變量
3.設置環境變量函數:<stdlib.h>
(1)int putenv(char *str);
A.取形式爲name = value的字符串,放到環境表中,如果name已存在,先刪除其原來的定義
B.成功返回0,否則返回非0
C.可以自由地將傳遞給他的字符串直接放到環境中
(2)int setenv(const char *name, const char *value, int rewrite);
A.將name設置爲value. 如果name已存在,先刪除現有定義(rewrite != 0),不刪除舊值也不賦新值
B.需要分配存儲空間
(3)int unsetenv(const char *name);
A.刪除name的定義,不存在也不出錯
4.環境表和環境字符串通常存放在進程存儲空間的頂部
(1)增加一個字符串比較困難。因爲佔用頂部,不能再向更高地址擴展;下面是棧幀,也無法向更低地址方向擴展
九、函數setjmp()和longjmp():處理髮生在深層嵌套函數調用中的出錯情況,進程中非局部轉移
1.goto語句不能跨越函數,setjmp和longjmp爲非局部(在棧上跳過若干調用幀,返回到當前函數調用路徑上的某個函數中)goto
2.<setjmp.h>
(1)int setjmp(jmp_buf env);放在需要返回的上層函數中
A.直接調用(將所需的信息記入變量env),返回0;從longjmp返回,返回非0
B.在希望返回到的位置調用setjmp()
C.jmp_buf是某種形式的數組,存放在調用longjmp時能用來恢復棧狀態的所有信息
D.需要在另一個函數中引用env,通常將env定義爲全局變量
(2)void longjmp(jmp_buf env, int val);放在發生錯誤的下層函數中
A.檢查到錯誤時,調用long_jmp()
B.val值非0,作爲setjmp()的返回值,區分多個longjmp()
3.longjmp()返回後,變量的值未知
十、函數getrlimit()和setrlimit():查詢/更改進程的資源限制
1.<sys/resource.h>
Int getrlimit(int resource, struct rlimit *rlptr);
Int setrlimit(int resource, const struct rlimit *rlptr);
(1)成功返回0,否則非0