Для начала функция инициализации
struct list *initialize(void)
{
struct list * l = NULL;
return l;
}
не имеет большого смысла. Вы можете просто написать в main
struct list *l = NULL;
Или функция initialize
может выглядеть как
inline struct list *initialize(void)
{
return NULL;
}
Функция add_element
имеет дело с копией переданного списка.
int add_element(struct list *list_, void *v);
Таким образом, любые изменения копии не влияют на исходный список. Также неясно, почему второй параметр имеет тип void *
вместо типа int
.
Вы должны передать список по ссылке на функцию.
Функция может выглядеть следующим образом
int add_element( struct list **head, int value )
{
struct list *node = malloc( sizeof( struct list ) );
int success = node != NULL;
if ( success )
{
node->value = value;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
и вызывается, например, как
int i = 10;
if ( !add_element( &l, i ) )
{
puts( "Error: not enough memory." );
}
Вот демонстрационная программа
#include <stdio.h>
#include <stdlib.h>
struct list
{
int value;
struct list *next;
};
static inline struct list * initialize( void )
{
return NULL;
}
int add_element( struct list **head, int value )
{
struct list *node = malloc( sizeof( struct list ) );
int success = node != NULL;
if ( success )
{
node->value = value;
node->next = NULL;
while ( *head != NULL ) head = &( *head )->next;
*head = node;
}
return success;
}
void output( struct list *head )
{
for ( ; head != NULL; head = head->next )
{
printf( "%d -> ", head->value );
}
puts( "NULL" );
}
int main(void)
{
struct list *head = initialize();
const int N = 10;
for ( int i = 0; i < N; i++ )
{
add_element( &head, i );
}
output( head );
return 0;
}
Ее вывод
0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> NULL
Обратите внимание, что если к концу списка добавляется новый узел, то лучше определить список как двусторонний односвязный список.