从不兼容的指针类型 'char *' 初始化 'const char **'

initialization of 'const char **' from incompatible pointer type 'char *'

初学C,函数返回双星指针有问题

这是我的代码。

#include <stdio.h>
#include <stdbool.h>

#include "api.h"

void init() {
  // You can initiate and calculate things here
}

/**
 * Return the given list in reversed order. Each element in the given list contains a single character.
 * 
 * typedef struct {
 *   int count;
 *   const char * * elements;
 * } string_list;
 * 
 * list_of_chars: string_list
 * 
 * returns: string_list
 */
string_list reverse(string_list list_of_chars) {
  // Write your code here
  char X[list_of_chars.count];
  
  //X[0] = *list_of_chars.elements[0];
  
  for (int i = 0; i < list_of_chars.count;i++){
  X[i] = *list_of_chars.elements[i];
  }
  printf("%c", X[0]);

  string_list return_value = {
    .count = 0,
    .elements = &X[0],
  };
  return return_value;
}

但我正在从不兼容的指针类型 'char *' 获取 'const char **' 的初始化。我尝试了多种解决方案,但没有一个有效。

旁注: 正如我在热门评论中提到的,我只能在移动设备上进行操作。我回到办公桌前了。

问题是:

  1. X 是函数作用域,所以它在函数 returns 时超出作用域。我们需要使用malloc[所以我们需要stdlib.h]
  2. 因为elements是一个const char **,那么我们需要const char **X

我们需要使用[应该使用]strdup来复制元素。

否则,两个列表将共享相同的数据。这可能 想要的意图。但是,从问题描述中并不清楚正确的代码应该是什么。

大多数列表应该完全相互独立。原始代码 而不是 这样做。因此,列表正在共享数据。但是,如果这是真的,为什么还要创建一个单独的列表呢?我们可以通过反向索引 而无需 创建新列表来“反转”它:

for (int i = list.count - 1;  i >= 0;  --i)

所以,我选择了复制字符串。使用 -DNODUP.

编译时的原始行为(共享字符串)

这是重构后的代码:

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

#if 0
#include "api.h"
#else
typedef struct {
    int count;
    const char **elements;
} string_list;
#endif

void
init()
{
    // You can initiate and calculate things here
}

/**
 * Return the given list in reversed order. Each element in the given list contains a single character.
 *
 * typedef struct {
 *   int count;
 *   const char * * elements;
 * } string_list;
 *
 * list_of_chars: string_list
 *
 * returns: string_list
 */
string_list
reverse(string_list list)
{
    const char **X = malloc(sizeof(*X) * list.count);

    // share the strings
#if NODUP
    for (int i = 0; i < list.count; i++)
        X[list.count - 1 - i] = list.elements[i];

    // make lists independent (more usual/expected)
#else
    for (int i = 0; i < list.count; i++)
        X[list.count - 1 - i] = strdup(list.elements[i]);
#endif

    string_list ret = {
        .count = list.count,
        .elements = X,
    };

    return ret;
}

更新:

In the link above was the exercise page where we can choose GCC for C. I pasted your code exactly to the website bit still see same errors.

好吧,终于……;-)

  1. 该网站使用 古老 版本的 C 标准(例如 C99)。 没有strdup.
  2. 网站会[强行]做一个#include "api.h"才包含代码,所以和我用的定义有冲突。

这里是更正后的代码(在网站上运行成功):

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

#if 1
#include "api.h"
#else
typedef struct {
    int count;
    const char **elements;
} string_list;
#endif

void
init()
{
    // You can initiate and calculate things here
}

/**
 * Return the given list in reversed order. Each element in the given list contains a single character.
 *
 * typedef struct {
 *   int count;
 *   const char * * elements;
 * } string_list;
 *
 * list_of_chars: string_list
 *
 * returns: string_list
 */
string_list
reverse(string_list list)
{
    const char **X = malloc(sizeof(*X) * list.count);

    // share the strings
#if 1
    for (int i = 0; i < list.count; i++)
        X[list.count - 1 - i] = list.elements[i];

    // make lists independent (more usual/expected)
#else
    for (int i = 0; i < list.count; i++)
        X[list.count - 1 - i] = strdup(list.elements[i]);
#endif

    string_list ret = {
        .count = list.count,
        .elements = X,
    };

    return ret;
}

旁注:我会得到一本关于 C 的好书并研究它以获得更多关于 C 的基础知识。尝试使用“竞争”网站并不是最好的方式,海事组织。

如果对 C 语法和语义有更好的基本理解,您已经看到(但不理解)的一些问题会很明显。

这是一个列表:The Definitive C Book Guide and List