Mar. 18th, 2011 [entries|reading|network|archive]
simont

[ userinfo | dreamwidth userinfo ]
[ archive | journal archive ]

Fri 2011-03-18 13:33
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 – all you need is an extra value for the loop variable you've already got, and we already have a good special value for pointer variables in the form of 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-initial test, and we do the obvious thing of checking whether we've arrived back at head.

This is a cleaner solution than the switch-based one, because it doesn't interfere with case statements inside the user-provided loop body. It's far less exciting, but there we go.

[xpost |http://simont.livejournal.com/231512.html]

Link8 comments | Reply
navigation
[ viewing | March 18th, 2011 ]
[ go | Previous Day|Next Day ]