APUE 程序環境

2021-08-27 12:26:45 字數 2752 閱讀 7501

本文章介紹程序的環境

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提供的啟動 在程式的記憶體空間結構還沒有布局起來...