经常见到在main函数的括号里面有void或者int argc,char *argv[],那么这内容的含义是什么?
那么要搞清楚他的含义,就要从古老的命令行操作系统讲起。
在现代图形操作系统出现以前,人们与计算机交流的方式是在黑漆漆的背景下敲入由一个个字符组成的命令以及命令所带的参数。命令行是命令行环境下,用户输入的用于运行程序的行。假如有一个程序叫做Hello,那么在UNIX以及类UNIX系统中的运行方式为:
$Hello
或者在windows的DOS命令行下:
C>Hello
命令行参数是同一行中的同一行中的附加项,如:
$Hello -t --show
一个C程序可以读取这些附加项,并且为自己所用。C程序是通过main函数读取的,比如:
#include <stdio.h>这个程序编译为可执行程序repeat,下面是从命令行运行的结果:
int main (int argc,char *argv[])
{
int count;
printf ("The command line has %d arguments!\n",argc-1);
for (count=1;count<argc;count++)
{
printf ("%d:%s\n",count,argv[count]);
}
printf ("\n");
}
#./repeat abc def ghi
#The command line has 3 arguments!
#1.abc
#2.def
#3.ghi
那么他究竟是怎么工作的呢?下面解释一下:
C编译器允许main函数没有参数,或者有两个参数(有些编译器允许跟多的参数,但这是对标准的扩展)。当有两个参数时,第一个参数是命令行中的字符串个数,按照惯例(但不是必须的),这个int参数被称为argc(argument count)。系统使用空格判断一个字符串的结束,另一个的开始。因此,repeat例子中包括命令名在内有4个字符串。第二个参数是一个指向字符串的指针数组,命令行中的每一个字符串都被存储到内存中,并且分配一个指针指向它。按照惯例,这个指针数组被称为argv(argument value)。如果可以(有些系统不允许这样做),把程序名本身赋值给argv[0],接着把随后的第一个字符串赋值给argv[1],总结如下表:
argv[0] | 指向 | repeat(大多数系统) |
argv[1] | 指向 | abc |
argv[2] | 指向 | def |
argv[3] | 指向 | ghi |
现在就可以理解上面的程序为什么那样输出了。
当然可以有其他的方式声明argv,如:
int main (int argc,char **argv)
这种方式和上面的方式是等价的,它意味着argv是一个“指向字符的指针”的指针,两种方式均可以使用,但是我认为第一种方式更能体现argv代表一系列字符串。
顺便提一下,很多环境(包括UNIX和DOS)允许使用引号把多个单词集中在一个参数里面,如:
repeat “I am hungry” now
这个命令会把I am hungry赋值给argv[1],把字符串now赋值给argv[2]。