Altogether, it is much like (for a different type declaration of p): for (p = head; p && p->key < key; p = p->next) except that the p in my version is always a pointer to the p in this latter version. Specifically, it is a pointer to the variable containing the 'next' pointer in question. So it can be modified so as to change the sequencing of the list. p (in my version) starts out as pointing to the 'head' variable, so if the search ends there, assigning to *p is assigning to head. If the search continues, p ends up pointing to head->next, then to head->next->next, etc. Whenever the search ends, we have a pointer to the 'next' value which needs changing. Except that 'head' isn't a special case; the pointer might be to a 'next' member or it might be to the 'head' variable.