I think your troubles with the code is due to the code being "a bit poorly" written, i.e. less clear than it could be. I see three issues.
1) "typedef of pointer" makes it hard to understand what types are involved. Especially when it's not clear that a specific type is a pointer. A name like ListaDiElementi
is not (at least not to me) making it clear that this is a pointer. A better name could be ElementoLista_ptr
but overall it's better to avoid pointer typedef.
2) The function argument is named head
. This is confusing because we normally think of head
as the pointer to the first element of a list. But that's not what is going on here. The argument is really a double pointer and further it does not point to the first element. It points to next
pointers.
3) The if
constructs hides logic of the program.
So let's rewrite the code to get rid of the above while still keeping the same functionality:
typedef struct El {
int info;
struct El *next;
} ElementoLista;
void inserisci(ElementoLista **pNext) {
if ((*pNext) == NULL) return;
inserisci(&(*pNext)->next);
if(((*pNext)->info)%2 == 0) {
ElementoLista* aux = malloc(sizeof(ElementoLista));
aux->info = -1;
aux->next = *pNext;
*pNext = aux;
}
}
With this code it's easier to see that the code keeps calling it self recursively until it reaches the end. On the way back, i.e. as the function calls return, the code checks whether it needs to insert a "-1" node.
The same code with some comments to explain:
typedef struct El {
int info;
struct El *next;} ElementoLista;
// pNext is a pointer to the "next pointer" of the previous node
// Consequently (*pNext) is a pointer to the current node
void inserisci(ElementoLista **pNext) {
// Return if we have reached the end of the list
if ((*pNext) == NULL) return;
// Keep calling until the end is reached
inserisci(&(*pNext)->next);
// On the "way back" (i.e. as the recursive calls return) check
// if we need to insert a "-1" node
if(((*pNext)->info)%2 == 0) {
// We need a new node
ElementoLista* aux = malloc(sizeof(ElementoLista));
aux->info = -1;
// Make the new node point to current node
aux->next = *pNext;
// Update the next pointer to point to the new node
*pNext = aux;
}
}
When you understand this simplified version of the code, you should also understand the original version.