其中int是main函式的類型,雖然舊的編譯器使用void定義,或者不聲明main的類型也可以編譯,但是那是不好的做法,根據 ISO C和POSIX.1 的定義都應該將main顯式聲明為 int 類型的。argc是命令行參數的數目,argv是指向參數的各個指針構成的數組。與眾面向對象語言不同,C需要顯式的 argc 傳遞參數的個數,因為僅憑 argv 不能確定其大小。
當核心執行C程式時,在調用 main 前先調用了一個特殊的啟動例程,可執行程式檔案將此例程指定為程式的起始地址–這是有連線編輯器設定的,而連線編輯器則由C編譯器調用,啟動例程從核心取得命令行參數和環境變數值,然後為按上述方式調用main函式做好安排。
按照 ISO C的規定,一個進程可以登記最多32個(具體實現可能更多)由exit自動調用的函式,這些函式稱為終止處理程式,調用atexit函式來登記這些函式。#include int atexit(void (*func)(void)); 還記得之前介紹的函式指針嗎,atexit函式的參數的類型就是一個函式指針(函式地址),其返回值和參數都是 void 。注意:exit調用這些登記了的函式的順序與它們登記的順序相反,同一函式若登記多次,則會被調用多次。
一個C程式的啟動和終止流程:
可以看出核心使程式執行的唯一方法是調用一個exec函式。
命令行參數
命令行參數其實我們之前已經使用過了,基本了解了,對於Java和Go中的命令行參數方式也有所了解:Java通過一個String數組獲取命令行參數,而Go則通過設定 flag 可以非常方便地獲取特定的參數。
已初始化數據段(initialized data segment),保存程式中被初始化的全局變數(定義在任何函式之外)。例如:int maxcount = 99; 全局變數變數maxcount被保存在初始化數據段。
未初始化數據段(uninitialized data segment),也被稱為BSS(block started by symbol),這個段中的數據在程式執行之前被核心初始化為0或者null。;例如定義一個全局變數(定義在任何函式之外),long sum[1000]; 該變數保存在未初始化數據段中。