Чтобы упростить разработку будущих школьных заданий, я решил создать API (это то, что вы бы назвали его?) Для двух структур данных, которые я обычно использую - связанный список и хеш-таблицу.Стиль кодирования - перейдите по ссылке или перейдите по значению?
При разработке каждого из них я в конечном итоге со следующими двумя вставными функциями:
int list_insert(list *l, char *data, unsigned int idx);
int hash_insert(hash_table **ht, char *data);
list_insert()
функции (и всех функций списка) заканчивал тем, что передача по значению, так как я никогда не было необходимо непосредственно изменить сам файл list *
, если я не был malloc'ing или free'ing его. Однако, поскольку я хотел включить автоматическое переигрывание в моей хеш-таблице, я обнаружил, что мне пришлось передавать таблицу-ссылку вместо значения-значения в любой функции, которая могла бы заставить переименовать. Теперь я в конечном итоге с синтаксисом следующих:
list_insert(l, "foo", 3);
hash_insert(&ht, "foo");
Разница кажется мне немного странным, и я задавался вопросом, должен ли я изменить функции списка будет проходить по ссылке, а ради Консистенция в - - хотя ни одна из моих функций не понадобится использовать ее. Какой здесь типичный консенсус? Должен ли я передавать только по ссылке, если моя функция действительно нуждается в изменении своих аргументов или должна ли я передавать по ссылке для согласованности?
определения структуры:
typedef struct list_node list_node;
struct list_node {
char *data;
list_node *next;
list_node *prev;
};
typedef struct list list;
struct list {
list_node *head;
list_node *tail;
size_t size;
};
typedef struct hash_table hash_table;
struct hash_table {
list **table;
size_t entries;
size_t buckets;
float maxLoad;
unsigned int (*hash)(char*, unsigned int);
};
Список функций:
list *list_createList();
list_node *list_createNode();
void list_destroyList(list *l);
void list_destroyNode(list_node *n);
int list_append(list *l, char *data);
int list_insert(list *l, char *data, unsigned int idx);
int list_remove(list *l, char *data, int (*compar)(const void*, const void*));
void list_push(list *l, char *data);
char *list_pop(list *l);
int list_count(list *l, char *data, int (*compar)(const void*, const void*));
int list_reverse(list *l);
int list_sort(list *l, int (*compar)(const void*, const void*));
int list_print(list *l, void (*print)(char *data));
Хэш функции:
hash_table *hash_createTable(size_t buckets, float maxLoad, unsigned int (*hash)(char*, unsigned int));
void hash_destroyTable(hash_table *ht);
list *hash_list(const hash_table **ht);
int hash_checkLoad(hash_table **ht);
int hash_rehash(hash_table **ht);
int hash_insert(hash_table **ht, char *data);
void hash_stats(hash_table *ht);
int hash_print(hash_table *ht, void (*print)(char*));
Какая информация хранит 'hash_table' соответственно. «список» содержит? Возможно, изменение «list *», переданное по ссылке, имеет такой же смысл, как и модификация «hash_table *» на дальнейшее рассмотрение ... – Deduplicator
Можете ли вы сообщить, что именно делают ваши API и как выглядят ваши структуры? – Gopi
Предложите [Обзор кода] (http://codereview.stackexchange.com), а не здесь. – chux