Я был на собеседовании на должность С, в которой мне представили идиому, с которой я раньше не сталкивался. Это уловка, которая упрощает реализацию различных алгоритмов, включающих связанные списки, и мне интересно, сталкивался ли кто-нибудь еще с этим.
Скажем, у нас есть запись связанного списка, определенная так:
typedef struct _record
{
char* value;
struct _record* next;
} record;
Нам нужна функция, которая вставляет новую запись, чтобы весь список оставался отсортированным по значению в записях. Следующая реализация проще, чем все, что я бы использовал, хотя и менее читабельная.
void insert_sorted(record** r, const char* value)
{
record* newrec = NULL;
while(*r && strcmp(value, (*r)->value) > 0)
r = &((*r)->next); /* move r to point to the next field of the record */
newrec = malloc(sizeof(record));
newrec->value = strdup(value);
newrec->next = *r;
*r = newrec;
}
Когда вызывается функция, r указывает на указатель заголовка списка. Во время цикла while значение r обновляется, чтобы указывать на поле next
записи, которая находится непосредственно перед точкой, в которую мы хотим поместить новую запись. Последняя строка функции либо обновляет указатель заголовка списка ( если вставка происходит в начале) или next
поле предыдущей записи, что довольно круто.
Пара вопросов:
Мне показалось, что я довольно хорошо знаю C, и у меня довольно хорошо разобрались указатели и косвенные указания, но на это у меня ушло некоторое время, чтобы полностью понять.