稍微知道C语言的人就知道,C语言中的主函数通常具有如下的形式:
int main(int argc, char * argv[]);
其中argc记录参数的个数,argv则记录具体的参数,是一个参数数组。在默认情况下,argc==1,argv[0] == 程序名称。
假设编写如下的程序:
1 #include<stdio.h>
2 #include<stdlib.h>
3
4 int main(int argc,char *argv[])
5 {
6 char p1[100];
7 char p2[100];
8 char p3[100];
9
10 if(argv[1]){
11 strcpy(p1,argv[1]);
12 }else{
13 strcpy(p1,"hello");
14 }
15
16 if(argv[2]){
17 strcpy(p2,argv[2]);
18 }else{
19 strcpy(p2,"hello");
20 }
21
22 if(argv[3]){
23 strcpy(p3,argv[3]);
24 }else{
25 strcpy(p3,"hello");
26 }
27
28 printf("%s/n",p1);
29 printf("%s/n",p2);
30 printf("%s/n",p3);
31
32 return 0;
33 }
我想这个程序原本的目的是想在执行时传入三个参数,分别将它们打印出来。
例如执行 ./main hello world cc
并假定如果传入的参数少于3个,则默认的使用"hello" 代替。
例如执行./main 时期望输出hello hello hello
但是实际上,大家可以自己运行一下看看,我的输出结果是:
hello
ORBIT_SOCKETDIR=/tmp/orbit-wzy
HOSTNAME=wzy
表示argv[1]此时的确为null,但是argv[2]和argv[3]却不是空的。这是为什么呢?
因为main函数真正完整的形式是
int main(int argc,char *argv,char *envp[]);
参数argc指出了运行该程序时命令行参数的个数,数组argv存放了所有的命令行参数,数组envp存放了所有的环境变量。
环境变量一般以字符串"XXX=xxx"的形式存在,XXX表示变量名,xxx表示变量的值。
值得一提的是,argv数组和envp数组存放的都是指向字符串的指针,这两个数组都以一个NULL元素表示数组的结尾。
我们可以通过以下这个程序来观看传到argc、argv和envp里的都是什么东西:
int main(int argc, char *argv[], char *envp[])
{
printf("/n### ARGC ###/n%d/n", argc);
printf("/n### ARGV ###/n");
while(*argv)
printf("%s/n", *(argv++));
printf("/n### ENVP ###/n");
while(*envp)
printf("%s/n", *(envp++));
return 0;
}
这下该明白了吧,至于前面的例子中为什么argv[2]不为空,是因为argv数组和envp数组是连续存储的,
所以argv[2]的指针越界就指向了envp数组中的内容。