Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A nested and expandable for loop in C

I am writing a C program where I operate nested for loops, one within another, as follows:

for(i[0] = 0; i[0] < n[0]; i[0]++)
  for(i[1] = 0; i[1] < n[1]; i[1]++)
    for(i[2] = 0; i[2] < n[2]; i[2]++)
      {
       do_lot_of_work(i, n, 3);
      }

As you can see, the above code has three nested for loops. In my program, it accounts for 3 dimensions. However, I want to make my program expandable, which can account of any number of dimensions, on the fly, as the user wishes; i.e. for 4 dimensions, I wish to have four nested for loops, and do the work as do_lot_of_work(i,n,4). Similarly, for any number of dimensions.

My question is: how to make the aforementioned nesting of for loops expandable?

Please note that, in order to achieve the goal, I am willing to sacrifice the inner for loops, but wish to keep the first for loop, in order to make my program parallel with OpenMP.

like image 817
Chandra Shekhar Avatar asked Feb 10 '23 03:02

Chandra Shekhar


2 Answers

When the nesting level is not known at compile time, use recursion to achieve the same effect:

void do_work(int i[], int n[], int pos, int size) {
    if (pos == size) {
        // All i-s are set - we are ready to roll
        do_lot_of_work(i, n, size);
    } else {
        for (i[pos] = 0 ; i[pos] < n[pos] ; i[pos]++) {
            do_work(i, n, pos+1, size);
        }
    }
}
like image 155
Sergey Kalinichenko Avatar answered Feb 12 '23 17:02

Sergey Kalinichenko


Use a recursive function.

void tons_of_work( int i[], int n[], int dims ) {
    loop_level( 0, i, n, dims );
}

void loop_level( int level, int i[], int n[], int dims ) {
    if ( level == dims ) {
        do_lot_of_work( i, n, dims );
    } else {
        int * ilevel = & i[ level ];
        for ( *ilevel = 0; *ilevel != n[ level ]; ++ *ilevel ) {
            loop_level( level + 1, i, n, dims );
        }
    }
}

loop_level calls itself to produce nested loops, until the innermost loop level is reached. Then it starts to do "real" work instead.

like image 22
Potatoswatter Avatar answered Feb 12 '23 16:02

Potatoswatter