Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to condense multiple for loops with different initial values

Tags:

c++

In a function, I have several consecutive for loops with the same code but different initial values for the control variable. The initial values are obtained from inputs to the function. Ie,

void thisFunction( class A a){
  //some other code

  for (int i = a.x; i != 0; --i){
    code
  }

  for (int i = a.y; i != 0; --i){
    code
  }

  for (int i = a.z; i != 0; --i){
    code
  }

  //some other code
}

Is there any way to condense all the for loops into one loop so that when I make changes to the code within the loop, I won't have to change it for all three loops? An alternative is to write anotherFunction() with the initial values as input, but I need access to local variables in thisFunction().

  void anotherFunction(int in){
      for (int i = in; i != 0; --i){
        code
      }
  }

So is there another way to condense the loops?

Thank you.

like image 819
Spock Avatar asked Dec 01 '22 05:12

Spock


2 Answers

Your hunch is right - you'll have to refactor your code into a separate function. Local variables of thisFunction will become arguments to anotherFunction; often these will be passed by reference .

like image 163
MSalters Avatar answered Dec 21 '22 10:12

MSalters


EDIT: In most cases you should avoid doing this, and rather follow MSalter's answer. Just because you can, doesn't mean you should.

I am not sure how good an idea this is, but without any more context, a simple solution could be:

int starts[3] = { a.x, a.y, a.z };
for ( int var = 0; var < 3; ++var ) {
   for ( int i = starts[var]; i != 0; --i ) {
      // code
   }
}

Note that the values of the conditions are obtained once at the beginning of the function, that means that if the object a changes throughout the first loop, that change will not be visible in the later control loops. If you need that, the solution can be modified to store pointers.

EDIT: There is a comment suggesting the use of the size of the array. I did not add that here not to modify, but anyway, a better way of getting the array size is:

template<typename T, unsigned int N>
inline unsigned int array_size( T (&)[N] ) {
   return N;
}
//...
for ( int var = 0; var < array_size(starts); ++i ) {
like image 43
David Rodríguez - dribeas Avatar answered Dec 21 '22 09:12

David Rodríguez - dribeas