Errata
Ahem. In yesterday's post about iterating over a circularly linked list, I made a mistake. The construction I exhibited, because it completely skips any test at the start of the loop, will crash if the list is empty and hence its head pointer is NULL
.
Fortunately, this is fixable by putting an additional test in the switch statement:
switch ((elephant = head) == NULL)
while (elephant = elephant->next, elephant != head)
case 0:
Then if the head pointer is NULL
, the switch
's input value will be 1, so it won't execute anything in its body at all.
However, I now also realise that there's a better answer in the first place. One commenter yesterday observed (and I had also thought myself) that the problem would be easy if only you could declare an extra flag variable and use it to suppress the first loop test. You can't, under the constraints of C90 syntax, because there's nowhere to put the declaration that doesn't cause further syntactic problems. But actually, I just realised, you don't need an extra variable at all –NULL
. So you can just do this:
for (elephant = NULL;
elephant ? elephant != head : (elephant = head) != NULL;
elephant = elephant->next)
So if elephant
is NULL
on entry to the loop test clause, that's the signal that it's the very first iteration, and we reassign elephant
to the loop head pointer (and terminate if even that is NULL
). Otherwise, it's a non-head
.
This is a cleaner solution than the switch
-based one, because it doesn't interfere with case
statements inside the user-