C++main函数与命令⾏参数,退出程序
(除动态链接库dll,静态链接库lib⼯程外)所有的C++程序都必须有⼀个main函数。如果你编译⼀个没有main函数的C++exe⼯程,编译器会提⽰错误。main函数是你的代码开始执⾏的地⽅,但在main函数调⽤前,所有的没有被显⽰初始化的static类成员都被设置为零。在微软C++中,调⽤main函数前全局静态对象也会被初始化。main函数相对于其他函数⽽⾔有以下不同之处:
1. 不能被重载
2. 不能被声明为inline,内联函数
3. 不能被声明为static
4. 不能获取它的地址,Cannot have its address taken
5. 不能被调⽤
main函数并没有声明,因为它是语⾔内置的。如果有的话,其形式如下所⽰:
int main();
int main(int argc, char *argv[], char *envp[]);
Microsoft Specific
如果你的代码⽂件使⽤的是Unicode wide character,你可以使⽤wmain,是main函数的宽字符版本,其声明如下:
int wmain( );
int wmain(int argc, wchar_t *argv[], wchar_t *envp[]);
你还可以使⽤_tmain,该函数定义在tchar.h。_tmain被解释为main,除⾮你定义了_UNICODE(在这种情况下,_tmain被解释为wmain)。
如果main函数的返回值没有指定,编译器会提供⼀个值为零的返回值。另外,main wmain可以被声明为返回为void(没有返回值)。如果你将main wmain声明为void,那么你就不能通过return语句将exit code返回给程序的⽗进程或系统。在main wmain是void的时候,你需要使⽤the exit function来返回exit code。
END Microsoft Specific
Command line arguments
main或wmain的参数可以⽅便地在命令⾏中解析参数,并可以选择性地获取环境变量。argc argv的类型由语⾔进⾏定义。argc argv envp是典型的变量名称,但是你也可以任意命名:
int main( int argc, char* argv[], char* envp[]);
int wmain( int argc, wchar_t* argv[], wchar_t* envp[]);
这些变量的定义如下:
argc:⽤于表明argv变量中参数的个数的⼀个int值。argc的值总是⼤于等于1
argv:⼀个空终⽌符的string组成的数组,该参数由⽤户输⼊。按照惯例,argv[0]是该程序被调⽤的命令;argv[1]是第⼀个命令⾏参数,之后的是第⼆三。。。个参数,直到argv[argc],该参数总是NULL。
注意:
1. 第⼀个命令⾏参数总是argv[1],最后⼀个总是argv[argc-1]
2. By convention, argv[0] is the command with which the program is invoked. However, it is possible to
spawn a process using and if you
use both the first and second arguments (lpApplicationName and lpCommandLine), argv[0] may not be the executable name; use to retrieve the executable name, and its fully-qualified path.
envp
The envp array, which is a common extension in many UNIX systems, 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. 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 the wchar_t data type instead of char. The environment block passed to main and wmain is a "frozen" copy of the current environment. If you subsequently change the environment via a call to putenv or _wputenv, the current environment (as returned by getenv or _wgetenv and the _environ or _wenviron variable) will change, but the block pointed to by envp will not change. See for information on suppressing environment processing. This argument is ANSI compatible in C, but not in C++.
例⼦:
/
/ argument_definitions.cpp
// compile with: /EHsc
#include <iostream>
#include <string.h>
using namespace std;
int main( int argc, char *argv[], char *envp[] ) {
int iNumberLines = 0; // Default is no line numbers.
// If /n is passed to the .exe, display numbered listing
// of environment variables.
if ( (argc == 2) && _stricmp( argv[1], "/n" ) == 0 )
iNumberLines = 1;
/
/ Walk through list of strings until a NULL is encountered.
for( int i = 0; envp[i] != NULL; ++i ) {
if( iNumberLines )
cout << i << ": " << envp[i] << "\n";
}
}
解析C++命令⾏参数
Microsoft C / C ++启动代码在解释操作系统命令⾏上给定的参数时使⽤以下规则:
参数由空格(while space)分割,空格可能是space,也可能是tab
The caret character (^) is not recognized as an escape character or delimiter.字符^并不会被识别为转义字符或分隔符。命令⾏参数在传递给argv数组前,完全由系统的command-line parser处理。
由双引号(“”)包围的字符串不管⾥⾯有多少个空格都会被解释为⼀个参数,带有引号的字符串可以嵌⼊到⼀个参数中
以反斜杠(\)开头的双引号(即:\")被解释为双引号字符。A double quotation mark preceded by a backslash (\") is interpreted as a literal double quotation mark character (").
斜杠(backslash)按照字⾯意思进⾏解释,不管它是否在双引号之前
如果偶数个斜杠后⾯跟着⼀个双引号,则每连续的两个斜杠被解释为⼀个斜杠到argv中,双引号被解释为字符串定界符,具体看下⾯的表格
如果奇数个斜杠后⾯跟着⼀个双引号,则每连续的⼀对(pair)斜杠被解释为⼀个斜杠,双引号被解释为''到argv(and the double quotation mark is "escaped" by the remaining backslash, causing a literal double quotation mark (") to be placed in argv)Results of parsing command lines
Command-Line Input argv[1]argv[2]argv[3]
"abc" d e abc d e
a\\b d"e f"g h a\\b de fg h
a\\\"b c d a\"b c d
a\\\\"b c" d e a\\b c d e
例⼦:
// command_line_arguments.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
int main( int argc, // Number of strings in array argv
char *argv[], // Array of command-line argument strings
char *envp[] ) // Array of environment variable strings
{
int count;
// Display each command-line argument.
cout << "\nCommand-line arguments:\n";
for( count = 0; count < argc; count++ )
cout << " argv[" << count << "] "
<< argv[count] << "\n";
}
通配符扩展Wildcard expansion
你可以使⽤通配符-问好(?)和星号(*)-⽤于在命令⾏上指定⽂件名和路径变量。
Command-line arguments are handled by a routine called _setargv (or _wsetargv in the wide-character environment), which by default does not expand wildcards into separate strings in the argv string array. For more information on enabling wildcard expansion, refer to . Customizing C++ comman
d-line processing
Microsoft Specific
If your program does not take command-line arguments, you can save a small amount of space by suppressing use of the library routine that performs command-line processing. This routine is called _setargv and is described in . To suppress its use, define a routine that does nothing in the file containing the main function, and name it _setargv. The call to _setargv is then satisfied by your definition of _setargv, and the library version is not loaded.
Similarly, if you never access the environment table through the envp argument, you can provide your own empty routine to be used in place of _setenvp, the environment-processing routine. Just as with the _setargv function, _setenvp must be declared as extern "C".
Your program might make calls to the spawn or exec family of routines in the C run-time library. If it does, you shouldn't suppress the environment-processing routine, since this routine is used to pass an environment from the parent process to the child process.
END Microsoft Specific
退出程序
在C++中,可以使⽤如下三种⽅式退出程序:
1. 调⽤exit函数
2. 调⽤abort函数
3. 在main函数中执⾏return语句
exit函数
exit函数是在头⽂件<stdlib.h>中声明的,⽤于结束C++程序。传递给exit函数的值作为程序的return code或exit code被传递给操作系统。通常情况下,返回⼀个零表⽰程序成功地结束。你可以使⽤常量EXIT_FAILURE,EXIT_SUCCESS来表明程序是成功退出,还是失败退出,这两个常量也定义在<stdlib.h>。
在main函数中使⽤return语句与调⽤exit函数并将return的值作为其参数是等价的。
abort函数
abort函数也是在<stdlib.h>头⽂件中声明的。exit与abort函数的不同之处在于exit允许C++运⾏时终⽌进程(run-time termination processing)⽣效(调⽤全局对象的析构函数),⽽abort函数是⽴即终⽌程序。abort函数绕过(bypass)已初始化的全局静态对象的正常销毁过程,并绕过使⽤atexit函数指定的任何特殊过程。
atexit函数
使⽤atexit函数可以指定⼀些特殊⾏为在程序结束前执⾏。在执⾏退出处理函数前,不会再atexit函数调⽤前销毁已经初始化的全局静态对象。 No global static objects initialized prior to the call to atexit are destroyed prior to execution of the exit-processing function. return statement in main
在main函数中使⽤return语句与调⽤exit函数是等价的。看下⾯的例⼦:
// return_statement.cpp
#include <stdlib.h>
int main()
{
exit( 3 );
return3;
}
上⾯例⼦中的exit和return在功能上是等价的。然⽽,C++要求main函数有返回类型,⽽不是返回⼀个void。However, C++ requires that functions that have return types other than void return urn语句允许你从main函数中返回⼀个值。
静态对象的销毁Destruction of static objects
当你调⽤exit或在main函数中使⽤return时,静态对象以它们初始化时相反的顺序进⾏销毁(如果atexit函数存在的话,则这些对象的销毁晚于atexit),下⾯的例⼦展⽰了静态对象的初始化和清除是如何⼯作的。
在下⾯的例⼦中,静态对象sd1 sd2是在进⼊main函数之前创建及初始化的。在程序通过return结束后,sd2⾸先被销毁,之后是sd1。ShowData类的析构函数关闭与这些静态对象相关联的⽂件。
// using_exit_or_return1.cpp
#include <stdio.h>
class ShowData {
public:
// Constructor opens a file.
ShowData( const char *szDev ) {
errno_t err;
err = fopen_s(&OutputDev, szDev, "w" );
}
// Destructor closes the file.
~ShowData() { fclose( OutputDev ); }
// Disp function shows a string on the output device.
字符串函数注册登录void Disp( char *szData ) {
fputs( szData, OutputDev );
}
private:
FILE *OutputDev;
};
// Define a static object of type ShowData. The output device
// selected is "CON" -- the standard output device.
ShowData sd1 = "CON";
// Define another static object of type ShowData. The output
// is directed to a file called "HELLO.DAT"
ShowData sd2 = "hello.dat";
int main() {
sd1.Disp( "hello to default device\n" );
sd2.Disp( "hello to file hello.dat\n" );
}
上述代码的另⼀种写法是通过block scope来声明ShowData对象,当离开范围(scope)时销毁这些对象:int main() {
ShowData sd1, sd2( "hello.dat" );
sd1.Disp( "hello to default device\n" );
sd2.Disp( "hello to file hello.dat\n" );
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论