Как я могу создать C LinkedList, который содержит динамически установленные типы данных - PullRequest
0 голосов
/ 27 апреля 2018

В C:

struct node {
   int data;
   int key;
   struct node *next;
};  

Приведенная выше структура данных C может содержать только установленные типы данных, то есть int data и int key.

В Java:

List<?> objectList = new ArrayList<>();  

Как я могу создать C LinkedList, который содержит динамически установленные типы данных?

Идея такова:

struct node {
   <?> data;
   <?> key;
   struct node *next;
};  

Так что я могу сделать:

List<String> objectList = new ArrayList<>();  

ИЛИ

List<MyCustomObject> objectList = new ArrayList<>();  

в C

struct node {
   <String> data;
   <String> key;
   struct node *next;
};  

ИЛИ

struct node {
   <MyCustomObject> data;
   <MyCustomObject> key;
   struct node *next;
};  

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Вы не можете, потому что динамические типы данных не существуют в общем в C . Проверьте, прочитав стандарт C11 n1570 .

Что вы можете сделать, это реализовать какой-нибудь тегированный тип объединения и составить список, содержащий их (или, возможно, список, содержащий некоторые указатели , но вам нужно решить, о некоторых стратегиях управления памятью и соответствующих соглашениях о кодировании).

Как реализовать такие типы теговых объединений - это другой вопрос. Для вдохновения посмотрите на тип Glib GVariant (но есть и другие способы сделать это; один пример - тип значения Python, подробнее об этом читайте в главе расширение Python ; или в некоторых struct содержащие union или union из struct, все начинающиеся с общего различающего поля, или union указателей на такие struct и т. д.), и изучите исходный код этой реализации в Glib, который является свободным программным обеспечением .

Вы могли бы также рассмотреть некоторый метапрограммирующий подход , например. генерировать некоторый C-код из некоторого описания ваших типов данных. Посмотрите на SWIG или RPCGEN для вдохновения.

Кстати, библиотека заголовков SGLIB , в основном использующая многие препроцессоры (с огромными макросами C) для предоставления "универсальных" контейнеров.

Помните также о ABI и соглашениях о вызовах вашей реализации на C. В некоторых случаях это может помочь понять его (например, если вы решите использовать теговые указатели ). Обратите внимание, что многие базовые типы C (int, long, char, указатели на данные , указатели на функции ) имеют существенно разные представления (разные размеры, разные выравнивания , различные способы передачи в качестве аргументов и возврата в качестве результатов - например, в различных регистрах процессора или в стеке вызовов ) и, возможно, даже в разных адресных пространствах (вспомните Гарвардскую архитектуру , где указатели функций находятся в другом пространстве, чем данные, и могут иметь размеры, отличные от указателей данных).

0 голосов
/ 27 апреля 2018

Данные должны быть void *. Затем вам нужно будет неявно привести его к тому типу указателя, которым он должен быть.

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