Инициализация 'const char **' из несовместимого типа указателя '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;
}

Но я получаю инициализацию «const char **» из несовместимого типа указателя «char *». Я пробовал несколько решений, но ни одно из них не сработало.

@Dai это в комментариях к коду над функцией

Craig Estey 14.05.2022 19:46
X находится в области действия функции (в стеке). Он выходит из области видимости, когда функция возвращается. Вы хотите: char *X = malloc(list_of_chars.count);
Craig Estey 14.05.2022 19:50

Я не понял, в чем польза комментариев над кодом (например, функция инициализации и структура). Но я попытался выделить указатель X с возвратом X вместо &X, но все равно не работал. может я что-то пропустил.

Ali Amma 14.05.2022 19:55

Я пропустил первоначальный замысел. Вы хотите: char **X = malloc(list_of_chars.count * sizeof(*X)); и X[list_of_chars.count - 1 - i] = strdup(*list_of_chars.elements[i]);

Craig Estey 14.05.2022 20:01

неявное объявление функции 'strdup'; Вы имели в виду 'strcmp'? [-Werror=неявное-объявление-функции] 30 | X[list_of_chars.count - 1 - i] = strdup(*list_of_chars.elements[i]); | ^~~~~~ | strcmp solution.c:30:36: ошибка: присваивание 'char *' из 'int' делает указатель целым без приведения [-Werror=int-conversion] 30 | X[list_of_chars.count - 1 - i] = strdup(*list_of_chars.elements[i]); | ^

Ali Amma 14.05.2022 20:09

Кроме того, .count = list_of_chars.count

Craig Estey 14.05.2022 20:09

Пробовал, но получил неявное объявление функции 'strdup'; Вы имели в виду 'strcmp'? И ошибка: присваивание 'char *' из 'int' делает указатель из целого числа без приведения

Ali Amma 14.05.2022 20:11

Ой, я с мобильного. Удалить * из вызова strdup

Craig Estey 14.05.2022 20:12

Добавить: #include <string.h>

Craig Estey 14.05.2022 20:13

сделал это, но все равно ошибка :( *** X[list_of_chars.count - 1 - i] = strdup(list_of_chars.elements[i]);

Ali Amma 14.05.2022 20:16
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
10
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Примечание: Как я уже упоминал в верхних комментариях, я был ограничен тем, что мог делать на мобильном телефоне. Я снова за своим столом.

Проблемы были:

  1. X находится в области действия функции, поэтому выходит за ее пределы, когда функция возвращается. Нам нужно использовать 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. Попытка использовать «конкурентные» веб-сайты — не лучший способ, IMO.

Ряд проблем, которые вы видели (но не понимали), были бы очевидны при лучшем базовом понимании синтаксиса и семантики C.

Вот список: Полное руководство и список книг C

Большое спасибо за ответ. Я попробовал, но получил вот это * решение.c:10:3: ошибка: конфликтующие типы для 'string_list' * примечание: предыдущее объявление 'reverse' было здесь * : неявное объявление функции 'strdup'; Вы имели в виду 'strcmp'? [-Werror=неявный- app.futureskill.com/exercise/5f609c49aa3c5b44f6359a26

Ali Amma 14.05.2022 21:44

@AliAmma Попробуйте использовать мой опубликованный код точно (т.е. скопируйте и вставьте его). Он компилируется чисто даже с -Wall -O2. Вы должны смешивать и сочетать. Я закомментировал: #include "api.h" [потому что вы этого не опубликовали] и скопировал определение struct из комментариев к функции. Если вы сделаете «оба», они будут конфликтовать. Я не понимаю, почему вы ссылаетесь на код питон.

Craig Estey 14.05.2022 21:51

@AliAmma Кроме того, я добавил необходимые [но отсутствующие] утверждения #include. Таким образом, просто скопировать обновленную функцию может быть недостаточно.

Craig Estey 14.05.2022 21:57

В приведенной выше ссылке была страница упражнений, где мы можем выбрать GCC для C. Я вставил ваш код точно на веб-сайт, но все еще вижу те же ошибки.

Ali Amma 14.05.2022 22:03

Спасибо за ваш ответ и ваше предложение. сделаю как ты сказал :)

Ali Amma 14.05.2022 22:30

Другие вопросы по теме