c - 将 char * 与 char ** 作为参数传递给 C 中的函数

标签 c char parameter-passing

我读过一些关于在 C 中传递 char * 的讨论。

stackoverflow: passing-an-array-of-strings-as-parameter-to-a-function-in-c
stackoverflow: how-does-an-array-of-pointers-to-pointers-work
stackoverflow: whats-your-favorite-programmer-ignorance-pet-peeve
drexel.edu: Character arrays

其中许多包括对数组的讨论,但我想远离它。

我正在编写一个示例程序来自学如何在 C 中传递 char *char **。这是一个传递 char * 的练习,没有使用(指向)数组。也不用担心执行效率。 :-)

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void get_args_works(int, char **, char **);
void get_args_broken(int, char **, char *);
char *get_string(int, char **);

int main(int argc, char **argv)
{
  char *string_works;
  char *string_broken;

  get_args_works(argc, argv, &string_works);
  get_args_broken(argc, argv, string_broken);

  printf("in main string_works (%p) = %s\n",string_works,string_works);
  free(string_works);

  printf("in main string_broken (%p) = %s\n",string_broken,string_broken);
  free(string_broken);
}

void get_args_works(int argc, char **argv, char **string)
{
    *string = get_string(argc, argv);
    printf("in get_args_works %p string %s\n",*string,*string);
}

void get_args_broken(int argc, char **argv, char *string)
{
  string = get_string(argc, argv);
  printf("in get_args_broken %p string %s\n",string,string);
}

char * get_string(int argc, char **argv)
{
  int i;
  char *string;
  string = malloc(40);

  // placeholder in case -s switch not found below
  strcpy(string,"-s switch not found below");

  for(i = 0; i < argc; i++)
    {
      if(argv[i][0] == '-')
        {
          switch(argv[i][1])
            {
            case 's':
              // release above malloc(40) for "-s switch not found below"
              free(string);
              // make room for storing variable
              string = malloc(strlen(argv[++i]) + 1);
              // the argv just after -s
              strcpy (string,argv[i]);
              break;
            }
        }
    }
  return string;
}

您还可以查看 same code on github

上面的代码有点 self 记录。 main() 声明了两个 char * 变量,并将它们作为参数传递给各自的 get_args() 函数。

每个 get_args() 函数调用 char * get_string(int, char **),使用完全相同的调用(但收集返回值的方式不同)。

get_string() 工作正常;它执行 malloc() 并将指针返回给调用函数。该代码有效,并且每个 get_args() 函数都按我的预期接收返回值。

但是,当 get_args() 函数返回到 main() 时,为什么取消引用的指针值返回到 main(来自 get_args_works(),而不是指针的值(来自 get_args_broken())?

(即我可以看到,如果我在作为参数发送时取消引用指针 (&string_works),它会起作用。但是为什么呢?不是 char * string_broken 已经一个指针?为什么它在作为参数发送时需要“额外的”取消引用?)

我希望得到一个成功的答案来解释您(是的,您)如何概念化发送 char * 作为参数与接收它作为函数的返回值。

最佳答案

int get_args_broken(int argc, char **argv, char *string)
{
  string = get_string(argc, argv);
  printf("in get_args_broken %p string %s\n",string,string);
}

您只是在修改 string 本地(自动)变量。这对调用者来说是不可见的。请注意,这意味着您正在释放 main 中的野指针。

错误的原因是一样的:

int get_sum(int sum, int a, int b)
{
  sum = a + b;
}

是;参数按值复制。此外,您不会返回 int(正如您声明的那样)。

int get_args_works(int argc, char **argv, char **string)
{
    *string = get_string(argc, argv);
    printf("in get_args_works %p string %s\n",*string,*string);
}

是正确的(除了缺少返回)。您没有修改 string,这毫无意义。您正在 string 中的位置修改对象,在本例中为 char *

编辑:如果有一个调用 main 的函数,并且您想将该函数的变量设置为不同的 char **,则您需要将 argv 增加三倍 *。例如

void trip_main(int *argc, char ***argv)
{
  *argc = 10; 
  *argv = malloc(*argc * sizeof(char *));
}

void caller()
{
  char **argv;
  int argc;
  trip_main(&argc, &argv);
}

关于c - 将 char * 与 char ** 作为参数传递给 C 中的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4242908/

相关文章:

bash - 将 ASCII 中的 Char 值保存在 bash 变量中

c - 如何将数组传递给这样的函数 : void fooboo(char array[i]);

c - C 中 Malloc() 的段错误

c++ - C++ 中的 char* 问题

c - 为什么多个线程得到相同的 "tid?"

c - 在指针 C 中保存多个字符(动态内存)

linux - 如何将密码传递给bash脚本

c# - 将 Image 对象作为参数从 C# 传递到 Python

从摄氏度到华氏度的转换返回 0.00

从 system() 调用 ksh 脚本导致段错误