c/c++之:main函数参数

简介:

一、文章来由

一直知道但是没有深究的东西。

二、参数解释

说简单点就是:

int argc;//表示读入字符串个数
char *argv[];//指针数组,用来存放读入的字符串
AI 代码解读

程序的意思逐个输出所有读入的字符串,每个字符串间空一个制表符间隔。

由于main函数不能被其它函数调用,因此不可能在程序内部取得实际值。那么,在何处把实参值赋予main函数的形参呢?

实际上,main函数的参数值是从操作系统命令行上获得的。当我们要运行一个可执行文件时,在DOS提示符下键入文件名,再输入实际参数即可把这些实参传送到main的形参中去。

DOS提示符下命令行的一般形式为: C:>可执行文件名 参数 参数…… (也可以选择“开始”菜单“运行”命令:可执行文件名 参数 参数……)

Visual Studio中修改命令行参数:项目—>项目属性—>属性配置—>调试—>命令参数

例如:

#include <iostream>
using namespace std;

int main(int argc,char *argv[],int a,int b)
{

    cout<<argc<<endl;

    while(argc-- > 1)
        printf("%s\n",*++argv);

    cout<<a<<endl;
    cout<<b<<endl;

    return 0; 
}
AI 代码解读

运行结果见图:

这里写图片描述

最后显示命令行中输入的参数。如果上例的可执行文件名为e24.exe,存放在A驱动器的盘内。因此输入的命令行为:
C:>a:e24 BASIC foxpro FORTRAN
则运行结果为:
BASIC
foxpro
FORTRAN
该行共有4个参数,执行main时,argc的初值即为4。argv的4个元素分为4个字符串的首地址。执行while语句,每循环一次argv值减1,当argv等于1时停止循环,共循环三次,因此共可输出三个参数。在printf函数中,由于打印项*++argv是先加1再打印, 故第一次打印的是argv[1]所指的字符串BASIC。第二、三次循环分别打印后二个字符串。而参数e24是文件名,不必输出。

三、注意

(1)main函数可以不带参数,也可以带参数,这个参数可以认为是main函数的形式参数。C语言规定main函数的有效参数只能有两个(如果是多个,其实是随机值)。

ANSI-C(C89/C99)的话main()函数有2种主要形式。

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

上面第二种,也可写成int main(int argc, char **argv)
argv[argc]放空指针(NULL指针)。
argc和argv可以用别名。

另外,还有一种受系统限制的形式:
int main(int argc, char *argv[], char *envp[])
前两个参数同第二种,第三个参数envp[]放环境变量。
这个形式很少用。

所以严格讲,
ANSI-C 推荐的带参数的 main() 函数只有上面第二种这一种。

(2)C语言还规定argc(第一个形参)必须是整型变量(或者可以隐式强转成int的,比如char也是可以的,但是double不行),argv( 第二个形参)必须是指向字符串的指针数组。

(3)但是应该特别注意的是,main的两个形参和命令行中的参数在位置上不是一一对应的。因为 main 的形参只有二个,而命令行中的参数个数原则上未加限制。argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。
例如有命令行为:

C:\>E24  BASIC  foxpro  FORTRAN
AI 代码解读

由于文件名E24本身也算一个参数,所以共有4个参数,因此argc取得的值为4。argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数。数组元素初值由系统自动赋予。其表示如图所示:

这里写图片描述

四、命令行参数转换

// 例如运行:
rec.exe  4  5.2
argc 等于 3, argv[0] 是 "rec.exe", argv[1] 是 "4", argv[2] 是 "5.2".

//主函数里若有:
int x;
float y;
char s[80];

strcpy(s,argv[0]);  // 程序名存入了 s
sscanf(argv[1],"%d",&x);  // x 得到数值4
sscanf(argv[2],"%f",&y);  // y 得到数值 5.2
AI 代码解读

五、C和C++中常见的几种形式

(1) main() 
(2) int main() 
(3) int main(void) 
(4) int main(int, char**) 
(5) int main(int, char*[]) 
(6) int main(int argc, char **argv) 
(7) int main(int argc, char *argv[]) 
(8) int main( int argc, char *argv[], char*envp[]) 
(9) void main(void)
AI 代码解读

(1)是(3)的简写。不推荐使用。
(2)是(3)的简写。在C++中是正确的形式。
(3)在C和C++中都是正确的形式。推荐使用。(还有缺省int的main(void)形式)。
(4)和(5)是不用参数时的一种写法。编译器级别高时会警告。不推荐使用。
(6)是(7)的另外写法。两种都可以,凭个人爱好。
(7)是带参数的正确的形式。推荐使用。
(8)是一种很少用的写法,且受系统限制。
(9)一般不认为是正确的写法。但是在嵌入式系统中有使用(包括void main()形式)


参考资料

[1] http://blog.csdn.net/yhawaii/article/details/7361302
[2] http://www.cnblogs.com/zerocc/archive/2010/12/17/1909642.html

目录
打赏
0
0
0
0
17
分享
相关文章
【C++11】可变模板参数详解
本文详细介绍了C++11引入的可变模板参数,这是一种允许模板接受任意数量和类型参数的强大工具。文章从基本概念入手,讲解了可变模板参数的语法、参数包的展开方法,以及如何结合递归调用、折叠表达式等技术实现高效编程。通过具体示例,如打印任意数量参数、类型安全的`printf`替代方案等,展示了其在实际开发中的应用。最后,文章讨论了性能优化策略和常见问题,帮助读者更好地理解和使用这一高级C++特性。
119 4
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
168 6
|
4月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
63 0
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
49 3
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
720 1
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
94 0
C++入门6——模板(泛型编程、函数模板、类模板)
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等