我正在研究Unix系统调用(execvp
)并且对此代码感到困惑。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]){
if(argc < 2){
perror("little arguments");
return -1;
}
execvp(argv[1], &argv[1]);
return 0;
}
我的问题是:为什么execvp
的第二个参数&argv[1]
?根据我对execvp的了解,第二个参数应该是一个命令数组(例如ls
-l
),我不认为&argv[1]
是一个命令数组。它只是一个字符串的地址,对吧?但是此代码与任何命令完美匹配(例如./a.out ls
,./a.out ls -l
,...)。
答案 0 :(得分:0)
继续上述两条评论:
这只是一个字符串的地址,对吗?
右。 的地址(例如指向的指针)字符串。 execvp
需要char *const argv[]
作为第二个参数。 (一个指向char 的const指针数组)。 &argv[1]
只提供 const指针数组的起始地址为char 。
由于你有一个指向char的指针数组,一个可视化正在发生的事情的简单方法就是printf
数组中每个指针(每个字符串)的内容。您可以通过索引进行迭代,或者声明指向第一个指针的指针,并通过简单地使用指针算法迭代每个指针。
一个简单的例子就是向代码中添加一个快速char **p = &argv[1];
,然后迭代将传递给execvp
(直到结束NULL
)的指针,看看是什么正在通过。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char* argv[]){
if(argc < 2){
perror("little arguments");
return -1;
}
int n = 1; /* declare a counter variable */
char **p = &argv[n]; /* declare a pointer to pointer to argv[1] */
while (*p) /* iterate over each pointer, and index */
printf ("points to argv[%d]: '%s'\n", n++, *p++);
execvp(argv[1], &argv[1]);
return 0;
}
示例使用/输出
$ ./bin/execvp ls -l dat
points to argv[1]: 'ls'
points to argv[2]: '-l'
points to argv[3]: 'dat'
total 892
-rw-r--r-- 1 david david 31 May 6 2016 11nums.txt
...
仔细看看,如果您对评论或答案有疑问,请告诉我。