Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

understanding this form of for loop in c

I have come across this For loop in c and I am struggling to make sense of it this is the loop Context: loop is going over a linked list

POINTER **prev=head, *curr, *next;

 for(curr = *head; curr; prev = &curr->link, curr = curr->link)

To my knowledge I can gather that curr will begin at the head of the list. what is curr; does this just mean the pointer current is not NULL? normally in that section it would be something like i < 5;

And lastly, prev = &curr->link, curr = curr->link - I have never seen a comma separating the incrementor (if thats what it is) I also dont understand what that section is doing.

Could someone possibly break this loop down for me to help me understand what is going on?

like image 232
william_ Avatar asked Apr 29 '21 02:04

william_


2 Answers

what is curr; does this just mean the pointer current is not NULL?

Correct. The second clause of a for loop is the controlling expression, and the loop continues as long as the controlling expression does not compare equal to 0. Since curr is a pointer, it will only be equal to 0 if it is a NULL pointer.

And lastly, prev = &curr->link, curr = curr->link - I have never seen a comma separating the incrementor (if that's what it is) I also don't understand what that section is doing.

The comma here in the third clause of the for loop is an instance of the comma operator. This operator evaluates its left operand, discards the value of that operand, then evaluates the right operand. In this context, using the comma operator allows us to assign a value to two variables in a single expression.

Specifically, this expression sets the prev pointer to point to the address of the link member of the current node, then sets the curr pointer to point to the next node in the list. The reason for prev being a pointer-to-pointer is presumably to allow either the current node to be removed or for a new node to be inserted before the current node, while also allowing for the special case of *head potentially being updated.

like image 159
dbush Avatar answered Oct 02 '22 14:10

dbush


Compact, isn't it? Beautiful.

https://en.wikipedia.org/wiki/For_loop#1972:_C/C++

for (initialization; condition; increment/decrement)
    statement

Initialization

curr = *head;

Is executed once at the start of the loop. curr is the iterator, and it starts at whatever head points too.

Condition

curr; True if curr is not NULL. False if curr is NULL (a peculiarity in C where 0 or NULL equate to False, and anything not 0 or NULL equates to True). The condition is checked at the beginning of each loop iteration. If true then the loop goes around again. If False, the loop exits.

Increment/Decrement

Here you encounter the odd looking comma operator: https://en.wikipedia.org/wiki/Comma_operator

This part of the loop is executed at the end of the loop iteration, before the Condition is checked for the next iteration. Using the comma operator, two operations have been squeezed in here:

Set prev to be the curr link (that's what makes sense to me, though I think something else may be meant by prev here):

prev = &curr->link

Now set curr to be the next link in the list:

curr = curr->link

The link list is thus traversed:

  • Initialization: start curr at head
  • Condition: test if curr has reached the end (i.e. NULL)
  • Loop
  • Increment/Decrement: move curr to the next link; keep the previous link (what was curr) in prev
  • Condition: ...
  • Loop
  • Increment/Decrement: ...
  • ...
like image 22
Jevon Kendon Avatar answered Oct 02 '22 14:10

Jevon Kendon