关于main函数参数之一——C/C++中命令行参数的原理 | |||
|
argc: 整数, 为传给main()的命令行参数个数。
argv: 字符串数组。
argv[0] 为程序运行的全路径名;
argv[1] 为在DOS命令行中执行程序名后的第一个字符串;
argv[2] 为执行程序名后的第二个字符串;
....................
argv[argc]为NULL。
如下图:
给你贴段话,仔细看看就明白了
main函数的参数
前面介绍的main函数都是不带参数的。因此main 后的括号都是空括号。实际上,main函数可以带参数,这个参数可以认为是 main函数的形式参数。C语言规定main函数的参数只能有两个, 习惯上这两个参数写为argc和argv。因此,main函数的函数头可写为: main (argc,argv)C语言还规定argc(第一个形参)必须是整型变量,argv( 第二个形参)必须是指向字符串的指针数组。加上形参说明后,main函数的函数头应写为:
main (argc,argv)
int argv;
char *argv[];或写成:
main (int argc,char *argv[])
由于main函数不能被其它函数调用, 因此不可能在程序内部取得实际值。那么,在何处把实参值赋予main函数的形参呢? 实际上,main函数的参数值是从操作系统命令行上获得的。当我们要运行一个可执行文件时,在DOS提示符下键入文件名,再输入实际参数即可把这些实参传送到main的形参中去。
DOS提示符下命令行的一般形式为: C:/>可执行文件名 参数 参数……; 但是应该特别注意的是,main 的两个形参和命令行中的参数在
位置上不是一一对应的。因为,main的形参只有二个,而命令行中的参数个数原则上未加限制。argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。例如有命令行为: C:/>E6 24 BASIC dbase FORTRAN由于文件名E6 24本身也算一个参数,所以共有4个参数,因此argc取得的值为4。argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数。数组元素初值由系统自动赋予。其表示如图6.8所示:
main(int argc,char *argv){
while(argc-->1)
printf("%s/n",*++argv);
}
本例是显示命令行中输入的参数如果上例的可执行文件名为e24.exe,存放在A驱动器的盘内。
因此输入的命令行为: C:/>a:e24 BASIC dBASE FORTRAN
则运行结果为:
BASIC
dBASE
FORTRAN
该行共有4个参数,执行main时,argc的初值即为4。argv的4个元素分为4个字符串的首地址。执行while语句,每循环一次 argv值减1,当argv等于1时停止循环,共循环三次, 因此共可输出三个参数。在printf函数中,由于打印项*++argv是先加1再打印, 故第一次打印的是argv[1]所指的字符串BASIC。第二、 三次循环分别打印后二个字符串。而参数e24是文件名,不必输出。
下例的命令行中有两个参数,第二个参数20即为输入的n值。在程序中*++argv的值为字符串“20”,然后用函数"atoi"把它换为整型作为while语句中的循环控制变量,输出20个偶数。
#include"stdlib.h"
main(int argc,char*argv[]){
int a=0,n;
n=atoi(*++argv);
while(n--) printf("%d ",a++*2);
}
本程序是从0开始输出n个偶数。指向指针的指针变量如果一个指针变量存放的又是另一个指针变量的地址, 则称这个指针变量为指向指针的指针变量。
1. 如果是命令行, 在命令行中执行编译整个C/C++工程的命令为devenv.exe myproject.sln /build Debug 或 devenv.exe myproject.sln /build Release.
但在Ant中使用exec Task 来执行, 能够正确执行, 但是看不到输出. 似乎是devenv.exe重定向了控制台的输出. 试了半天Ant调用VC2005编译工程的两个问题_LFF'S, 通过下面的方式能够解决:
<exec executable="cmd.exe" failοnerrοr="true" dir="${basedir}/cpp">
<arg value="/c devenv myproject.sln /build Debug"/>
</exec>
这样就能正常显示编译的结果了.
2. Debug/Release的问题
在项目的ant脚本中, 通过${build.type}来控制是Release或者Debug. 自然在编译C/C++的部分同样想通过这个来控制.于是把上Ant调用VC2005编译工程的两个问题_LFF'S面一行改为
<arg value="/c devenv myproject.sln /build ${build.type}"/>
但是不行, 编译出来的东西始终是Debug版. 后来怀疑${build.type}在这没有正确识别, 所以VC2005按照默认的Debug来编译. 后来测试了一下, 发现上面那样写不行, 应该把各个参数拆开, 就能正确替换成Debug/Release: /// 参数不能放在一行
<exec executable="cmd.exe" failοnerrοr="true" dir="${basedir}/cpp">
<arg value="/c"/>
<arg value="devenv"/>
<arg value="MyProject.sln"/>
<arg value="/build"/>
<arg value="${build.type}"/> //这样才能正确替换
</exec>
如何用MinGW 命令行编译链接c/c++ - zoudaokou2006的专栏 - 优快云博客
默认分类 2009-08-19 17:21:12 阅读235 评论0 字号:大中小
如何用MinGW 命令行编译链接c/c++ TE>收藏 TE>
一直用VS,看现在Eclipse很火,便想弄一下玩玩,用到了MINGW,继而用到了GCC,对GCC相当的不熟悉,从头开始学一些简单的吧。
简单的GCC用法~
gcc命令提供了非常多的命令选项,但并不是所有都要熟悉,初学时掌握几个常用的就可以了,到后面再慢慢学习其它选项,免得因选项太多而打击了学习的信心。
一. 常用编译命令选项
假设源程序文件名为test.c。
1. 无选项编译链接
用法:#gcc test.c
作用:将test.c预处理、汇编、编译并链接形成可执行文件。这里未指定输出文件,默认输出为a.out。编译成功后可以看到生成了一个a.out的文件。在命令行输入./a.out 执行程序。./表示在当前目录,a.out为可执行程序文件名。
2. 选项 -o
用法:#gcc test.c -o test
作用:将test.c预处理、汇编、编译并链接形成可执行文件test。-o选项用来指定输出文件的文件名。输入./test执行程序。
3. 选项 -E <大写,注意>
用法:#gcc -E test.c -o test.i
or <gcc -E -o test.i test.c>
作用:将test.c预处理输出test.i文件。
4. 选项 -S <大写,注意>
用法:#gcc -S test.i
作用:将预处理输出文件test.i汇编成test.s文件。
5. 选项 -c
用法:#gcc -c test.s
作用:将汇编输出文件test.s编译输出test.o文件。
6. 无选项链接
用法:#gcc test.o -o test
作用:将编译输出文件test.o链接成最终可执行文件test。输入./test执行程序。
7. 选项-O
用法:#gcc -O1 test.c -o test
作用:使用编译优化级别1编译程序。级别为1~3,级别越大优化效果越好,但编译时间越长。输入./test执行程序。
二. 多源文件的编译方法
如果有多个源文件,基本上有两种编译方法:
[假设有两个源文件为test.c和testfun.c]
1. 多个文件一起编译
用法:#gcc testfun.c test.c -o test
作用:将testfun.c和test.c分别编译后链接成test可执行文件。
2. 分别编译各个源文件,之后对编译后输出的目标文件链接。
用法:
#gcc -c testfun.c //将testfun.c编译成testfun.o
#gcc -c test.c //将test.c编译成test.o
#gcc testfun.o test.o -o test //将testfun.o和test.o链接成test
以上两种方法相比较,第一中方法编译时需要所有文件重新编译,而第二种方法可以只重新编译修改的文件,未修改的文件不用重新编译。
引文来源 如何用MinGW 命令行编译链接c/c++ - zoudaokou2006的专栏 - 优快云博客
C++项目在VS2010中的并行构建调优
如何在命令行上构建?
/MP设置来自项目文件,因此在命令行上进行设置作用是一样的,它是整个MSBuild的一部分,在命令行上构建和在Visual Studio中构建是一样的效果吗?在Visual Studio中设置的全局并行设置不会影响到命令行,你必须亲自给msbuild.exe传递/m参数,这个参数是可选的,如果你不设置,它就使用CPU的数量,但和Visual Studio开箱即用的特性不一样,在命令行中如果不指定/m参数,它只会使用1颗CPU,这个问题可能在将来的版本中会得到修正。
图8 命令行构建参数
如果想给/MP选任意的值,你可以设置一个环境变量,或象Visual Studio那样传递一个属性CL_MPCount。
在每个项目上都设置/MP是很烦人的,怎么才能提高设置效率?
你可能想在多个项目上使用/MP,但你又不想在每个项目上都设置一遍,Visual Studio解决这类问题的办法是使用属性表。首先从“视图”菜单打开“属性管理器”,根据你使用的设置它的确切位置可能不一样,下面是一个C++项目设置的位置。
图9 视图菜单中的属性管理器
在一个项目上点击右键,选择“添加新的属性表”:
图10 给项目添加新的属性表
我给它取了一个名字叫做“Multipro**p.props”,你将会看到该项目的所有配置都将添加这个属性表,在它上面点击右键,你将看到与项目相同的属性窗口,但这个时候你编辑的是属性表,再次将“Multi-processor Compilation”设为“YES”。关闭属性窗口,在属性管理器中选择属性表,然后点击“保存”。
C++项目在VS2010中的并行构建调优
现在可以在编辑器中打开新建的Multipro**p.props文件,我的看起来如下:
图11 在编辑器中打开Multipro**p.props
仔细查看这个项目文件,你可以看到属性表通过一个Import标签应用到每个配置中了,这一点和C++中的#include非常类似。
图12 通过Import引用属性表
现在我们就可以重用之前在项目文件中的定义了,于是我可以在属性管理器中选中多个项目,然后点击右键,选择“添加现有属性表”。
图13 为多个项目同时指定属性表
OK!现在所有项目编译时都带有/MP参数了。
在某些情况下,你可能想要更简单一点,例如,你可能想要删除大量的属性表,幸运的是,MSBuild 4.0有一个强大的,完整的对象模型,你可以使用它,再编写几行代码就可以搞定这种工作了。
如果你不想通过图形界面进行设置,完全可以自己手动进行编辑,例如,在VS自己的构建中,我们在每个项目的顶级都设置了一套属性。
图14 手动设置项目顶级属性
在这里我们定义了所有类型的全局设置,并导入了其它设置,我将在以后的文章中介绍组织大型构建树的方法。