Установка массива указателей

#arrays #c #struct #function-declaration #double-pointer

Вопрос:

я выполняю небольшое упражнение по загрузке массива указателей (двойной указатель) в структуру. У меня есть следующее определение в файле заголовка:

 #include <stdio.h>

#define LEN (5)

typedef struct sample_s {
    int num;
    char *name;
}sample_t;

typedef struct new_sample_s {
    char *string;
    sample_t **sample_arr;
}new_sample_t;

sample_t table[LEN] = {
    {0, "eel"},
    {1, "salmon"}, 
    {2, "cod"},
    {3, "tuna"},
    {4, "catfish"}
};
 

и используя определения в этом файле .c:

 #include "test.h"

void print_new_sample_array(sample_t **sample_arr) {
    int len = sizeof(table)/sizeof(new_sample_t);
    for(int i = 0; i < len; i  ){
        printf("The array element is: %sn", sample_arr[i]->name);
    }
}

int main() {

    new_sample_t new_sample;
    new_sample.sample_arr = table;

    print_new_sample_array(new_sample.sample_arr);

    return 0;
}
 

У меня есть два вопроса:

Во-первых, я не уверен, как правильно загрузить table сообщение об new_sample.sample_arr ошибке здесь:

 test.c: In function ‘main’:
test.c:13:27: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
     new_sample.sample_arr = table;
                           ^
 

Во-вторых, я не уверен, как я могу ссылаться на свойства каждого элемента в sample_arr . Например, когда я делаю следующее, программа выдает ошибку:

 for(int i = 0; i < LEN; i  ){
    printf("This is the elem in the array: %s", new_sample[i]->name);
}
 

Я пытаюсь узнать больше о концепции двойного указателя и о том, почему я сделал это неправильно. Я был бы очень признателен, если бы ответ содержал sample_arr двойной указатель as

Спасибо!

Комментарии:

1. «Во-первых, я не уверен, как правильно загрузить таблицу в сообщение об ошибке new_sample.sample_arr здесь:» => вы этого не делаете, тип > new_sample неправильный. Попробуй sample_t *sample_arr; .

2. @AnttiHaapala Я думаю, что лучшим вопросом должно быть, как загрузить массив с двойным указателем. С тех пор, как я пытаюсь этому научиться. Я проверил, что sample_t *sample_arr это работает, но не обязательно помогает мне понять двойной указатель 🙂

3. Вам нужно начать с массива указателей, например char *table[] = {"cod", "tuna"}; , у вас есть массив struct .

4. new_sample.sample_arr является указателем на указатель на sample_t структуру, в то время table как является указателем на кучу sample_t структур. Я предлагаю что-то вроде new_sample.sample_arr = amp;table .

5. @Я пытаюсь делать или не делать, нет никакой попытки 😀 Вы задаете неправильные вопросы. Здесь вам не нужен двойной косвенный указатель.

Ответ №1:

В этом заявлении о назначении

 new_sample.sample_arr = table;
 

правый операнд (после неявного преобразования массива в указатель на его первый элемент) имеет тип sample_t * , в то время как левый операнд имеет тип sample_t ** из-за объявления элемента данных

 sample_t **sample_arr;
 

Неявного преобразования типа sample_t * в тип не существует sample_t ** . Итак, компилятор выдал сообщение.

Вы должны объявить элемент данных как

 sample_t *sample_arr;
 

и соответственно объявление функции будет выглядеть так

 void print_new_sample_array(sample_t *sample_arr);
 

И внутри функции вызов printf будет выглядеть так

 printf("The array element is: %sn", sample_arr[i].name);