指向数组的指针返回初始地址

时间:2016-04-23 05:26:58

标签: c arrays pointers parameter-passing

我正在看这个创建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); } } ); }); }); 怎么样?

2 个答案:

答案 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)向该函数发送lineargv指针时,该函数会收到 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>