為什麼有些主程式(main)有三個參數?

為什麼有些main主程式會有三個變數在參數列上?

這個問題在書上有時會被提及,但是通常都不作說明,或要求你去查閱其他資料或使用手冊。在GNU C library第25章Program Basics中有詳細的說明,許多剛踏入Linux作程式的新手們都應該詳細閱讀此章的基礎知識。

其實第三個參數就是系統環境變數,執行程式時由系統直接傳遞給程式,我們可以利用這個變數客制化我們的程式本身,得到多數程式放置的位置、常用的分隔符號、主系統檔案位置等等。在Linux系統上,有工具是依照這些環境變數來工作的,並依此變化出許多特殊的使用方法。


以下為GNU C Library 25.1的原文說明:

25.1 Program Arguments

The system starts a C program by calling the function main. It is up to you to write a function named main—otherwise, you won't even be able to link your program without errors.
In ISO C you can define main either to take no arguments, or to take two arguments that represent the command line arguments to the program, like this:

 int main (int argc, char *argv[])

The command line arguments are the whitespace-separated tokens given in the shell command used to invoke the program; thus, in `cat foo bar', the arguments are `foo' and `bar'. The only way a program can look at its command line arguments is via the arguments of main. If main doesn't take arguments, then you cannot get at the command line.

The value of the argc argument is the number of command line arguments. The argv argument is a vector of C strings; its elements are the individual command line argument strings. The file name of the program being run is also included in the vector as the first element; the value of argc counts this element. A null pointer always follows the last element: argv[argc] is this null pointer.

For the command `cat foo bar', argc is 3 and argv has three elements, "cat", "foo" and "bar".

In Unix systems you can define main a third way, using three arguments:

 int main (int argc, char *argv[], char *envp[])

The first two arguments are just the same. The third argument envp gives the program's environment; it is the same as the value of environ. See Environment Variables. POSIX.1 does not allow this three-argument form, so to be portable it is best to write main to take two arguments, and use the value of environ.

印出環境變數的小程式
/**
 * 程式功能 : 將3參數形式的主程式中,第三個代表環境變數的內容列印出來。
 * 程式語言 : C
 * 編譯器 : gcc-4.2.3
 * 撰寫者 : Mirror Chiu
 * 撰寫時間 : 2008-05-07
 * 其他說明 : 印出的方法與參數其實差不多。
 */
#include <stdio.h>

int main (int argc, char *argv[], char *envp[])
{
 int i;
 puts("Content-Type: text/plain\n\n");
 for (i=0 ; envp[i] != NULL ; ++i)
  printf("'%s'\n", envp[i]);
 return 0;
}


但是不一定要用第三個參數才能接收系統的環境變數,可以引入環境標頭檔,使用裡面的函式,依然能夠得到系統環境參數,你可以參考GNU C Library 25.4 Environment Variables得到這些函式的資訊。

/**
 * 程式功能 : 在2參數形式的主程式中,讀取環境變數的內容並列印出來。
 * 程式語言 : C
 * 編譯器 : gcc-4.2.3
 * 撰寫者 : Mirror Chiu
 * 撰寫時間 : 2008-05-07
 * 其他說明 : 可參考The GNU C Library 25.4 Environment Variables的部分獲得其他資訊。 
 */
#include <stdio.h>
#include <stdlib.h> // 使用環境變數要引入的標頭檔案

extern char ** environ;

int main (int argc, char *argv[])
{
 int i;
 puts("Content-Type: text/plain\n\n");
 for (i=0 ; environ[i] != NULL ; ++i)
  printf("'%s'\n", environ[i]);
 
 // 如果只是要需要特定的環境變數,只需要用getenv()函式即可。
 // char * getenv (const char *name)
 // printf("SOMETHING_YOU_WANT='%s'\n", getenv ("SOMETHING_YOU_WANT"));

 return 0;
}

留言