1.引入
一般情況下,main函數帶有兩個參數,分別為int argc和char* argv[],各自表示參數個數、參數選項。比如在cmd視窗中運行ping www.csdn.net -t,那麼傳到ping程式的main函數的兩個參數argc=3,argv[]={"ping","www.csdn.net","-t"}。
查看MSDN,可選的原型為int main(intargc,char*argv[],char*envp[]);。前兩個參數比較熟悉,第3個參數就很陌生了。那麼,envp裝的是什麼,有什麼用?
2.列印環境變數
編寫一個小程式,把envp裡的資料列印出來,代碼如下:
/*++ envp.cpp - print environment viaries *decription:include<tchar.h> so as to support generic-text mapping *created:2011-08-14 16:58 *author:btwsmile--*/#include<tchar.h>#include<cstdio>#include<cstdlib>using namespace std;int _tmain(int argc,_TCHAR* argv[],_TCHAR* envp[]){for(int i=0;;++i){if(envp[i]){_tprintf_s(_TEXT("%d:%s\n"),i,envp[i]);}else break;}system("pause");return 0;}
其結果為:
0:ALLUSERSPROFILE=C:\ProgramData
1:APPDATA=C:\Users\root\AppData\Roaming
2:asl.log=Destination=file
3:CommonProgramFiles=C:\Program Files\Common Files
4:COMPUTERNAME=ROOT-PC
5:ComSpec=C:\Windows\system32\cmd.exe
6:DXSDK_DIR=C:\Program Files\Microsoft DirectX SDK (June 2010)\
7:FP_NO_HOST_CHECK=NO
8:HOMEDRIVE=C:
9:HOMEPATH=\Users\root
10:LOCALAPPDATA=C:\Users\root\AppData\Local
11:LOGONSERVER=\\ROOT-PC
12:MOZ_PLUGIN_PATH=C:\Program Files\Foxit Software\Foxit Reader\plugins\
13:NUMBER_OF_PROCESSORS=4
14:OS=Windows_NT
15:PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
16:PROCESSOR_ARCHITECTURE=x86
17:PROCESSOR_IDENTIFIER=x86 Family 6 Model 15 Stepping 11, GenuineIntel
18:PROCESSOR_LEVEL=6
19:PROCESSOR_REVISION=0f0b
20:ProgramData=C:\ProgramData
21:ProgramFiles=C:\Program Files
22:PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
23:PUBLIC=C:\Users\Public
24:SESSIONNAME=Console
25:SystemDrive=C:
26:SystemRoot=C:\Windows
27:TEMP=C:\Users\root\AppData\Local\Temp
28:TMP=C:\Users\root\AppData\Local\Temp
29:USERDOMAIN=root-PC
30:USERNAME=root
31:USERPROFILE=C:\Users\root
32:VisualStudioDir=C:\Users\root\Documents\Visual Studio 2010
33:VS100COMNTOOLS=D:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\
34:windir=C:\Windows
35:PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Program Files
\Common Files\Thunder Network\KanKan\Codecs;D:\Program Files\Microsoft Visual St
udio 10.0\;D:\Program Files\Microsoft Visual Studio 10.0\VC\bin
請按任意鍵繼續. . .
觀察結果不難發現,envp裡存放正是系統的環境變數,可以按右鍵電腦->屬性->進階系統設定->環境變數(Win7),開啟環境變數設定視窗,1所示。
圖1 系統內容變數設定視窗
把圖1所示視窗中的變數名稱、值與程式列印出來的結果對比,它們是一樣的。也就是說envp數組裡儲存的正式系統的環境變數。
3.envp的用途
MSDN上的解釋是這樣的:
Microsoft Specific
wmain( int argc, wchar_t *argv[ ], wchar_t *envp[ ] )
envp:
The envp array, which is a common extension in many UNIX systems【#1】, is used in Microsoft C++. It is an array of strings representing the variables set in the user's environment. This array is terminated by a NULL entry【#2】.
It can be declared as an array of pointers to char (char *envp[ ]) or as a pointer to pointers to char (char **envp). If your program uses wmain instead of main, use thewchar_t data type instead ofchar【#3】.
The environment block passed to main and wmain is a "frozen" copy of the current environment【#4】. If you subsequently change the environment via a call to putenv or _wputenv, the current environment (as returned by getenv/_wgetenv and the _environ/ _wenviron
variable) will change, but the block pointed to by envp will not change. See Customizing Command Line Processing for information on suppressing environment processing. This argument is ANSI compatible in C, but not in C++【#5】.
#1:許多UNIX作業系統中普遍擴充了對envp數組的支援;
#2:它儲存這使用者環境中的變數字串,以NULL結束。正因此,本文上面的例子用if(envp[i])來判斷是否列印完畢;
#3:envp可以是char*[]類型也可以是char**類型,本文上面的例子使用的是前者;如果使用寬字元集,則應使用wmain代替main,並使用wchar*[]或wchar**類型的envp。本文上面的例子使用tchar.h,使用了通用文本編程;
#4:envp一旦傳入,它就只是單純的字串數組而已,不會隨著程式動態設定發生改變。可以使用putenv函數即時修改環境變數,也能使用getenv即時查看環境變數,但是envp本身不會發生改變;
#5:這個版本對ANSI C相容,但對ANSI C++不相容。
envp用的不多,因此對它的作用並沒有argc和argv那樣清楚的理解。不過依據它的表現,筆者能夠想到的到envp的作用有兩點:
(1)為程式提供參考:程式的運行過程中需要參考環境變數作出決定,比如安裝程式必須知道系統預設的ProgramFiles,它可以通過envp查看到本系統的程式檔案夾在ProgramFiles=C:\Program Files,於是預設安裝目錄就設定定為C:\ProogramFiles;
(2)如果程式在運行過程中對環境變數做了修改,在它退出時想要恢複,這時就可以參照envp中的資料將環境變數恢複到程式執行前的設定。