c程式執行時,最開始執行的是啟動**,啟動**再去呼叫main函式,然後整個c程式都已執行。
由編譯器提供的,一般有兩種提供方式:①原始碼、②二進位制(gcc採用這種)
gcc -v [檔名] 可以檢視gcc編譯鏈結的詳細情況時,可以看到有很多*.o,這些 .o檔案就是gcc提供的啟動**。
在程式的記憶體空間結構還沒有布局起來之前,高階語言程式還無法執行,此時只能使用彙編,當利用彙編編寫的啟動**將高階語言的記憶體空間結構建立起來後,自然就可以執行c/c++等高階語言的程式了。對c程式的記憶體空間進行布局,得到c程式執行所需要的記憶體空間結構
比如從c記憶體空間中劃出一段空間,以「棧」的形式來管理。留下相應庫介面
如果程式使用的是動態庫的話,編譯時,動態庫**並不會被直接編譯到程式中,只會留下相應的介面,程式執行起來後,才會去對接庫**,為了能夠對接動態庫,啟動**會留下動態庫的對接介面。程序終止方式有兩種,一種是正常終止(主動),另一種是異常終止(被動)。
main中呼叫return關鍵字
return關鍵字的作用是返回上一級函式,如果main函式的子函式呼叫return的話,返回的上一級是main函式。如果main函式呼叫return的話,main函式所返回的上一級是啟動**。main函式呼叫return有兩種方式:程式任何位置呼叫exit函式(庫函式)(a)顯式呼叫
比如:return [返回值];
返回值的意義:返回值標記的了退出狀態,比如一般情況下。
return 0:正常結束
return -1:代表了某種操作失敗
return -2:代表了另一種的操作失敗
值的具體意義由開發者規定。使用echo $?可以檢視程式執行後的,main函式的返回值。如果main函式沒有返回值,查詢的結果為main函式中最後一次呼叫的子函式的返回值。
(b)隱式呼叫:不寫出return,當main函式中的最後一句**執行完畢後,會預設的呼叫return返回0。
其實,main函式呼叫return返回到啟動**後,啟動**也是呼叫exit函式來實現正常終止的。main函式呼叫return將返回值返回給啟動**後,啟動**又會呼叫exit(返回值)。程式任何位置呼叫_exit函式(系統呼叫)
exit是對_exit的封裝。_exit用法與exit一樣。被訊號強制終止,這就是異常終止。
(a) 自殺:自己呼叫abort函式,自己給自己發乙個sigabrt訊號將自己殺死。(b) 他殺:由別人發乙個訊號,將其殺死。
程序終止處理函式的註冊順序和呼叫順序剛好相反。呼叫atexit註冊時,會將「程序終止處理函式」的函式位址壓入程序棧中,當程序正常終止時,又會自動從棧中取出函式位址,並執行這個函式,實現程序的掃尾操作。在兩種情況下,登記的程序終止處理函式不會被呼叫:
(a)異常終止,不會呼叫。登記「程序終止處理函式」有什麼意義?(b)直接呼叫_exit來正常終止時,不會呼叫。
有的時候需要在程序正常終止時做一些掃尾操作,比如釋放記憶體相關的操作。如果不註冊程序終止處理函式的話,需要在每次程式正常終止前編寫相應的掃尾**,很繁瑣。為什麼呼叫exit、return正常終止時,會重新整理標準io的快取?
因為exit會呼叫fclose關閉所有的標準io。而呼叫fclose關閉標準io時,會自動呼叫fflush()重新整理資料。./a.out *** *** ——> 終端視窗程序(構建指標陣列) ——> os 核心 ——> 啟動** ——> main函式形參每乙個程序都在自己的記憶體空間中儲存了乙份自己的環境變數表。這個環境變數表的內容來自於環境變數檔案。
永久修改(直接修改環境變數檔案)
臨時修改(只對當前程序有效)
1.命令列(只對終端視窗有效)
(a)檢視:export 或 echo $[key]2.呼叫api(b)新增:export [key]=[value]
(c)修改:export [key]=[value] 或 export [key]=$[key]:[value]
(d)刪除:unset [key]
int putenv(char *string);int setenv(const char *name, const char *value, int overwrite);
int unsetenv(const char *name);
使用命令列視窗執行./a.out,那麼a.out程序就屬於「命令列視窗程序」的子程序,子程序的環境表是從父程序複製得到的。所以所有程序的「環境變數表」都是從父程序複製得到的,最原始程序的「環境變數表」則是從「環境變數檔案」中讀到的。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 程序環境
本文章介紹程序的環境 1.main函式 c程式總是從main函式開始執行的,其原型是 int main int argc,char argv argc是命令列引數的個數 argv是指向引數的各個指標所構成的陣列 2.程序終止 有8種方式可以讓程序終止,其中前5種為正常終止 1.從main返回 2.呼...