Search code examples
arrayscfor-looppointer-arithmetic

Iterating though an array of structs in C


Can someone explain this for loop to me?

struct {
  int lock;   // not used in Lab
  struct proc proc[NPROC];
} ptable;

void scheduler(void){
struct proc *p;

  acquire(&ptable.lock);
  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
    if(p == curr_proc || p->state != RUNNABLE)
      continue;

    // Switch to chosen process.
    curr_proc = p;
    p->state = RUNNING;
    break;
  }
  release(&ptable.lock);

}

Mostly I'm asking about the for loop

  for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){

What does assigning the pointer p to ptable.proc do? And how do I access the struct proc's members/variables?


Solution

  • Mostly I'm asking about the for loop

    for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
    
    p = ptable.proc
    

    Here the array ptable.proc decays into a pointer to the first element in the array and p is assigned this pointer. It's the same as doing p = &ptable.proc[0].

    p < &ptable.proc[NPROC]
    

    Here p is compared with the address one element outside the array bounds (out of bounds). ptable.proc[NPROC - 1] is the last element within bounds.

    p++
    

    This steps the pointer to point at the next struct proc in the struct proc array.

    So, the for-loop as a whole starts by making p point at the first struct proc in the array and iterates through all the elements in the array until p points outside the array, then it terminates the loop.

    Here's an alternative loop with the same result to visualize what's going on:

    // for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){
    for(int idx = 0; idx < NPROC; idx++) {
        p = &ptable.proc[idx];   // or:   p = ptable.proc + idx;
    
        // the rest of the loop body goes here ...
    }
    

    And how do I access the struct proc's members/variables?

    You dereference the pointer p with the -> operator to access the members of the element p is pointing at. p->state accesses the state member in the struct proc that p is currently pointing at.