【问题标题】:Why can't I evaluate "array to NULL" in a for loop?为什么我不能在 for 循环中评估“数组为 NULL”?
【发布时间】:2019-03-06 14:47:18
【问题描述】:

我正在尝试计算数组数组的元素以分配内存“res”,用于连接存储在“argv”中的每个字符串,包括 NULL 终止符。可能还有更多的错误要发现,但我不明白的第一个是/* length of arrays */ 中的argv[a][b] != NULL。为什么这是不可接受的,还有其他方法(无需硬编码或传递长度)来确定元素的数量?

使用:http://pythontutor.com/c.html#mode=edit

char    *ft_concat_params (int argc, char **argv)
{
    int len_argc = argc - 1,
        len_argv = 0;
    char *res = NULL;

    /* length of argvs */
    for (int a = 0; a < len_argc; a++) {
      for (int b = 0;argv[a][b] != NULL; b++) {
        len_argv++;
      }
    }

    /* allocate memory res -- freed by calling function! */
    res = malloc (len_argv * sizeof * res);
    if (!res) {
      ft_putstr ("not allocated res");
      free(res);
      return NULL;
    }

    /* concate strings */
    for (int a = 0; a < len_argc; a++) {
      int b = 0;
      while (argv[a][b] != '\0') {
        res = &argv[a][b];
        b++;
      }
      res[b] = '\0';
    }

    return res;
}

int   main(void)
{
  int argc = 4;
  char argv[3][6] = {
    {'s','t','a','r','t','\0'},
    {'s','t','a','r','t','\0'},
    {'s','t','a','r','t','\0'}
  };
  char *arr;

  arr = ft_concat_params (argc, argv);
  if (!arr)       /* validate return */
      return 1;

  free(arr);
}

【问题讨论】:

  • 您似乎在尝试复制程序参数传递给int main(int argc, char *argv[]) 的方式,但它们与您所做的不同。
  • '\0' 类似于 (char)0 = 一个值为 0 的字符。这用于终止 C 字符串,它与指向内存位置的指针 NULL 不同0
  • @MikNiller - 从技术上讲,'\0' 和 NULL 在许多系统上的数值为零,但我同意,不要混淆它们
  • @WeatherVane 我这样做是因为pythontutor.com/c.html#mode=edit 似乎没有办法将参数传递给 main。我应该如何声明数组?
  • 正如我写的:int main(int argc, char *argv[]) 请看What are the arguments to main() for? 编辑:哦,我明白了,网页不允许你。

标签: c for-loop multidimensional-array


【解决方案1】:

这一行:

char *res = 'NULL'; 

不将指针初始化为 NULL。 相反,它设置为一些奇怪的、无意义的 32 位值。

你想开始

char *res = NULL;  // NOTE:  No single-quotes around it.

【讨论】:

  • 其实这个值之前没有被设置,所以char *res;就足够了。但也因为你的图标完美地解释了你看到错误时的想法^^
【解决方案2】:
the first I don't understand is argv[a][b] != NULL
  • argv 具有类型 (char **)
  • argv[a] 的类型为 (char *)
  • argv[a][b] 的类型为 (char)

比较 argv[a][b] 和 NULL 就是比较一个字符和一个指针,这是不允许的,因为它没有意义。

【讨论】:

    【解决方案3】:

    主要问题是二维数组与char** 无关。指向指针的指针不能指向二维数组。它不是二维数组。它与二维数组不兼容。忘记指向指针的指针。

    除了当您有一个一维指针数组时 - 然后可以使用指针指向该数组的第一个元素。因此,如果您在 main() 中的代码是 char* argv[n] = { "hello", "world", ... },那么您使用 char** 的函数就会起作用。

    但事实并非如此。您在 main() 中有一个真正的二维数组。所以你必须相应地改变函数:

    char* ft_concat_params (int x, int y, char argv[x][y])
    {
      ...
      argv[i][j]  // now you can use this way of accessing
    

    【讨论】:

    • 根据我目前所学和测试: char *argv[] == char **argv ,还是仅适用于 main 函数?
    • @Mike 数组,当作为参数传递给函数时,会调整为指向数组第一个元素的指针。因此,如果您将数组char* [] 传递给函数,则参数的类型将是char**,因为它是指向char* [] 数组中第一个char* 元素的指针。函数声明为void f (char* foo[]) 或void f (char** foo) 也没关系,因为前者会被默默地翻译成后者。
    猜你喜欢
    • 2012-08-23
    • 2019-08-20
    • 1970-01-01
    • 2012-06-24
    • 2017-10-05
    • 2012-01-08
    • 1970-01-01
    • 2018-10-15
    • 1970-01-01
    相关资源
    最近更新 更多