第七章 高級環境
阿新 • • 發佈:2018-04-15
CP c編譯器 全局變量 register return AR 打開 close 編程 第七章 高級環境
7.2 main函數
C程序總是從main函數開始執行的。main函數的原型是:
int main(int argc, char *argv[]);
其中,argc是命令行參數的數目,argv是指向參數的各個指針所構成的數組。
當內核執行C程序的時候(使用一個exec函數),在調用main前先調用一個特殊的啟動例程。可執行程序文件將此啟動例程指定為程序的起始地址--
這是由連接編輯器設置的,而連接編輯器則是由C編譯器調用的。啟動例程從內核取得命令行參數和環境變量值,然後為按上述方式調用main函數做好安排。
7.3進程終止
有8種方式使進程終止。其中5種為正常終止,依次是:
說明使用atexit函數。
#include <stdlib.h>
#include <stdio.h>
static void my_exit1(void);
static void my_exit2(void);
int main(void)
{
if (atexit(my_exit2) != 0)
{
printf("can‘t register my_exit2\n");
}
if (atexit(my_exit1) != 0)
{
printf("can‘t register my_exit1\n");
}
if (atexit(my_exit1) != 0)
{
printf("can‘t register my_exit1\n");
}
printf("main id done\n");
return 0;
}
static void my_exit1(void)
{
printf("first exit handler\n");
}
static void my_exit2(void)
{
printf("second exit handler\n");
}
7.4命令行參數
當執行一個程序的時候,調用exec的進程可以將命令行參數傳遞給該新函數。
#include<stdio.h>
int main(int args, char *argv[])
{
int i;
for (i = 0; i<args; i++)
{
printf("argv[%d]:%s\n", i, argv[i]);
}
return 0;
}
7.5環境表
每個程序都接收到一張環境表。與參數表一樣,環境表也是一個字符指針數組。其中每個指針包含一個以null結尾的C字符串地址。全局變量
environ則包含了該指針數組的地址:extern char **environ;
7.6 C程序的存儲空間布局
C程序一直由下列部分構成:
- 從main函數返回
- 調用exit
- 調用_exit或_Exit
- 最後一個線程從期啟動例程返回
- 從最後一個線程調用pthread_exit
- 調用abort
- 接到一個信號
- 最後一個線程對取消請求做出響應
- 正文段。這是由CPU執行的機器指令部分。通常,正文段是可共享的,所以即使是頻繁的執行的程序在存儲器中也只需有一個副本。此外正文段常常是只讀的,以防止程序由於意外而修改其指令。
- 初始化數據段。通常將此段稱為數據段,它包含了程序中需明確地賦初值的變量。例如,在C程序中任何函數之外的聲明:int maxcoubnt =99; 使此變量以其初值存放在初始化數據段中。
- 未初始化數據段。通常將此段稱為bss段。這一名稱來源於早期匯編程序一個操作符,意思是“由符號開始的塊”,在程序開始執行前,內核將此段中的數據初始化為0或空指針。函數外聲明:long sum[10];
- 棧。自動變量以及每次函數調用時所需保存的信息都存放在此段中。每次函數調用時,其返回地址以及調用者的環境信息(如某些機器寄存器的值)都存放在棧中。然後,最近被調用的函數在棧上為其自動和臨時變量分配存儲空間。
- 堆。通常在堆中進行動態存儲分配。由於歷史形成的慣例,堆位於未初始化數據段和棧之間。
第七章 高級環境