You are not constrained to use a pointer to pointer.
It has to do more with what of the 2 ways you prefer to write your code. They also have pros and cons.
Now:
void pushToList(node **listHead, int val) {
node *temp = malloc(sizeof(node));
temp->value = val;
temp->next = *listHead;
*listHead = temp;
}
As you said the above will work.
void pushToList(node *listHead, int val) {
node *temp = malloc(sizeof(node));
temp->value = val;
temp->next = listHead;
listHead = temp;
}
That won't but the following
node *pushToList(node *listHead, int val) {
node *temp = malloc(sizeof(node));
temp->value = val;
temp->next = listHead;
return temp;
}
will also work.
In the first code you must pass the memory address of the pointer that points to the head of your list, not the memory address of the head of the list. The reason you do that is to have access to the pointer that points to the head of the list and change where it points (to the new node that will be the head)
In the last code you pass the memory address of the current head, not the memory address of the pointer that points to that memory so you can add the new node but the pointer that points to the head of your list remains unchanged so you return the new head and you save it to the pointer who points to the head.
I will post a picture soon of what it happens and they will all become clear.