本文章介紹程序的環境
1.main函式
c程式總是從main函式開始執行的,其原型是
int main(int argc, char **argv);
//argc是命令列引數的個數
//argv是指向引數的各個指標所構成的陣列
2.程序終止
有8種方式可以讓程序終止,其中前5種為正常終止
1.從main返回
2.呼叫exit
3.呼叫_exit或_exit
4.最後乙個執行緒從其啟動例程返回
5.最後乙個執行緒呼叫pthread_exit
6.呼叫abort
7.接到乙個訊號並終止
8.最後乙個執行緒對取消請求做出響應
3.exit函式
#include
void exit(int status);
void _exit(int status);
#include
void _exit(int status);
//_exit和_exit立即進入核心,exit則進行一些清理處理在進入核心
由於歷史原因,exit函式總是要執行乙個標準i/o庫的清理關閉操作fclose(),這將造成所有的緩衝區資料都被沖洗
unix shell:#echo $? 可以顯示程式的返回值
4.atexit函式
按照iso c規定,乙個程序可以登記多達32個函式,這些函式將由exit自動呼叫。
我們稱這些函式為終止處理函式,用下面的函式來登記這些函式:
#include
int atexit(void (*func)(void));
//成功返回0,出錯返回非零值
在程式即將結束的時候,呼叫登記過的函式,但是函式的執行順序和登記的順序是相反的
根據iso c和posix.2,exit函式首先呼叫各個終止處理函式,然後按需多次呼叫fclose函式,關閉所有開啟的流。
posix.1擴充套件了iso c的標準,它指定如若程式呼叫exec函式族的任一函式,則將清除所有已安裝的終止處理函式。
5.命令列引數
當執行乙個程式的時候,呼叫exec的程序可將命令列引數傳遞給新程式。
程式如下:
#include
#include
int main(
int argc, char *
*argv)
exit
(exit_success);}
6.環境表
每個程式都會接受一張環境表,這個表和參數列一樣是乙個字元指標陣列,每個指標包含以null介紹給有的c字串的位址
在程式中宣告
extern char **environ;
在程式中輸出環境表
for (i = 0; environ[i] != null; i++)
環境表的每個欄位的格式都是name=value
7.c語言的儲存空間布局
從歷史上將c語言一直由以下幾部分組成
正文段:這是由cpu執行的機器指令部分。正文段是共享的,在儲存器中只有乙個副本。另外正文段通常是唯讀的
初始化資料段: 通常將此段稱為資料段,它包含了程式中需明確的賦初值的變數。如:
c語言中:
int i = 0;
此變數存在初始化資料段中
非初始化資料段:通常將此段稱為bss段。在程式開始執行之前,核心將此段中的資料初始化為0或空指標。
棧:自動變數以及每次函式呼叫時所需儲存的資訊都存放在此段中。每次呼叫函式時,其返回位址以及呼叫者的環
境資訊都存放到棧中。然後,最近被呼叫的函式在棧上為其自動和臨時變數分配儲存空間。通過這種方式使用棧,
可以遞迴呼叫c函式。遞迴函式每次呼叫自身時,就使用乙個新的棧幀,因此乙個函式呼叫例項中的環境變數不會
影響到另乙個函式呼叫例項中的變數。
堆:通常在堆中進行動態儲存分配。堆位於非初始化資料段和棧之間。
size命令則報告正文段,資料段和bss段的長度
8.儲存器分配
iso c說明了三種用於儲存器空間分配的函式
#include
void *malloc(size_t size);
//分配指定位元組數的儲存區。此儲存區中的初始值不確定。
void *calloc(size_t nobj, size_t size);
//在記憶體的動態儲存區中分配nobj個長度為size的連續空間,儲存區中初始值均為0。
void *realloc(void *ptr, size_t newsize);
//將ptr所指向的儲存區重新分配,當增加長度的時候新增的訪問區中的初始值不確定。
//這三個函式若成功返回非空指標,失敗返回null
void free(void *ptr);
//釋放儲存區空間
9.setjmp和longjmp
在c語言中,goto語句是不能跨越函式的,最穩妥安全的跨越函式跳轉的函式是setjmp和longjmp
#include
int setjmp(jmp_buf env);
//若直接呼叫返回0,若從longjmp呼叫返回非0值
void longjmp(jmp_buf env, int val);
//setjmp設定返回的位置,longjmp中的val是跳轉後的返回值
APUE 程序環境
mian函式 c程式總是從main函式開始執行。main函式的原型是 int main int argc,char argv 其中,argc是命令列引數的數目,argv是指向引數的各個指標所構成的陣列。當核心執行c程式時,在呼叫main之前先呼叫乙個特殊的啟動例程。可執行程式檔案將此啟動例程指定為程...
APUE 程序環境
本文使用golang的syscall,os,golang.org x sys unix包 main是程式的入口,golang中也亦是如此 啟動乙個程式時啟動例程負責從核心獲取命令列引數和環境變數,維護到程式的記憶體布局中 後文描述 import os func exit code int 使程式主動...
APUE自學筆記 程序環境
c程式執行時,最開始執行的是啟動 啟動 再去呼叫main函式,然後整個c程式都已執行。由編譯器提供的,一般有兩種提供方式 原始碼 二進位制 gcc採用這種 gcc v 檔名 可以檢視gcc編譯鏈結的詳細情況時,可以看到有很多 o,這些 o檔案就是gcc提供的啟動 在程式的記憶體空間結構還沒有布局起來...