我正在看这个创建shell的小程序。 parse()
采用字符指针line
和字符指针数组argv
,保存argv
中每个单词的地址。
void parse(char *line, char **argv) {
while (*line != '\0') { /* if not the end of line ....... */
while (*line == ' ' || *line == '\t' || *line == '\n')
*line++ = '\0'; /* replace white spaces with 0 */
*argv++ = line; /* save the argument position */
printf("%p\n",*argv);
while (*line != '\0' && *line != ' ' &&
*line != '\t' && *line != '\n')
line++; /* skip the argument until ... */
}
*argv = '\0'; /* mark the end of argument list */
}
我不明白的是argv
以某种方式退回到函数退出后的第一个单词。主函数调用:
parse(line, argv); /* parse the line */
if (strcmp(argv[0], "exit") == 0) /* is it an "exit"? */
exit(0);
argv[0]
在line
之前line
的结尾处的chrome.browserAction.onClicked.addListener(function (tab)
{
chrome.tabs.query({active: true, currentWindow: true}, function(tabs)
{
chrome.tabs.sendMessage(tab.id, {method: "sendHTML"}, function(response)
{
var val = null;
if(response.data != null) {
lnks = parse_links(response.data);
val = setInterval(function(){
var total = lnks.length;
if (l < lnks.length) {
console.log(lnks[l]);
chrome.tabs.create({ url: lnks[l] });
l++;
} else {
clearInterval(val);
}
}, 5000);
}
}
);
});
});
怎么样?
答案 0 :(得分:2)
原因是参数是用C中的值传递的。用这种方式思考:
void func(int a)
{
a = 20;
}
int main()
{
int val = 10;
printf("%d", val);
func(val);
printf("%d", val);
}
在上面的两个印刷品中,打印出的值都是10.如果要在func中修改val,则必须传递其地址。指针也是如此。指针与任何其他参数一样按值传递。因此,如果您有这样的事情:
#include <stdio.h>
void func(char **argv)
{
while (*argv != 0) {
printf("%s\n", *argv);
argv++;
}
printf("*****done*****\n");
}
int main(int argc, char **argv)
{
func(argv);
printf("%s\n", argv[0]);
}
然后用:
运行它gcc a.c
./a.out hello how are you
输出将是:
./a.out
hello
how
are
you
*****done*****
./a.out
如果你希望argv在从函数返回时指向最后一个参数,那么你必须传递它的地址:
#include <stdio.h>
void func(char ***argv)
{
while (**argv != 0) {
printf("%s\n", **argv);
(*argv)++;
}
(*argv)--;
printf("*****done*****\n");
}
int main(int argc, char **argv)
{
func(&argv);
printf("%s\n", argv[0]);
}
现在的输出是:
./a.out
hello
how
are
you
*****done*****
you
答案 1 :(得分:2)
如果我了解混淆的地方,当您致电void parse(char *line, char **argv)
向该函数发送line
和argv
指针时,该函数会收到 COPY 每个指针与每个副本都有自己的地址。
因此,不管你对函数中的指针本身做了什么(例如,argv
遍历argv++, argv++
,main()
中永远不会看到这些更改,因为增量仅发生在main
参数向量的副本和argv
中的原始指针对任何一个都没有任何线索。
现在,如果您更改main
中任何单个字符串的内容,那么这些更改将在void parse(char **line, char ***argv)
中显示,但任何其他非内容修改更改仅对您的函数而言是本地的。
您可以更改函数中指针的唯一方法是将指针的地址传递给函数。这会给你一个main
的原型然后你可以在你的函数中更改指针iself并在char *tmp = (*argv)[0]; (*argv)[0] = (*argv)[1]; (*argv)[1] = tmp;
中显示这些更改(例如<div id="container">
<div class="baby"></div>
<div class="baby"></div>
<div class="baby"></div>
<div class="baby"></div>
</div>
<div id="someID">
<div class="baby"></div>
<div class="baby"></div>
<div class="baby"></div>
</div>
<div class="baby"></div>
<div class="baby"></div>
<div class="baby"></div>
)