Арифметика c двойных указателей со структурой данных - PullRequest
1 голос
/ 05 мая 2020

Я попытался написать хеш-таблицу и нашел этот репозиторий на github: введите здесь описание ссылки . Мне сложно понять этот код:

struct entry_s
{
    char* key;
    char* value;
    struct entry_s* next;
};

typedef struct entry_s entry_t;

struct hashtable_s 
{
    int size;
    struct entry_s** table;
};

typedef struct hashtable_s hashtable_t;

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

1) Почему здесь используется typedef struct entry_s entry_t; вместо

struct entry_s
{
    char* key;
    char* value;
    struct entry_s* next;
};entry_t; 

потому что, если я воспользуюсь вторым способом, у меня будет ошибка.

2) Что означает этот код: struct entry_s** table;

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

Ответы [ 2 ]

4 голосов
/ 05 мая 2020

Почему используется typedef struct entry_s entry_t; вместо

struct entry_s
{
    char* key;
    char* value;
    struct entry_s* next;
};entry_t;

Приведенный вами синтаксис неверен и не соответствует вашим представлениям. Последняя строка, };entry_t;, рассматривается как новый оператор, потому что ваш компилятор ожидает, что после каждого ; будет новый. Вы хотите написать следующий код:

struct entry_s
{
    char* key;
    char* value;
    struct entry_s* next;
} entry_t;

Эта структура представляет собой связанный список, вы можете видеть, что одно из полей (последнее) использует ту же структуру для хранения данных. Более абстрактно вы можете увидеть этот код, например:

struct my_linked_list_s
{
    T data;
    struct my_linked_list_s *next;
};

В C рекурсивный тип данных (то есть тот, который используется в собственном определении), требует указателя (по причинам измерения размера конструкции *), поэтому мы видим его в поле next. Затем, чтобы различать guish между «внутренним» использованием структуры и ее внешним использованием, мы определяем тип псевдонима:

typedef struct my_linked_list_s my_linked_list_t;

Или, в вашем случае:

typedef struct entry_s entry_t;

Это не обязательно, но ваша реализация решила это сделать. Вы можете увидеть соглашение об именах: _s для «структуры» и _t для «типа».

Потому что, если я использую второй способ, у меня будет ошибка.

Вам следует более внимательно читать сообщения об ошибках вашего компилятора, это помогло бы вам понять, что не так.

Что означает этот код: struct entry_s** table;

Это массив указателей. Ваша реализация выбрала использование связанных списков и указателей, эта функция четко описывает добавляемую часть.

Для лучшего обзора таблиц C ha sh см. этот ответ .

* Для определения размера структуры (sizeof(struct my_struct)) используется сумма размеров всех полей. Если бы мы определяли размер рекурсивной структуры без использования указателя (указатель имеет фиксированный размер для любого типа данных), тогда структура имела бы бесконечный размер. Поэтому, чтобы избежать этой проблемы, мы используем указатель.

0 голосов
/ 21 августа 2020

Ответ на второй вопрос: вы удаляете массив указателей, который может хранить указатели типа struct entry_s**.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...