7

Is there a way without using arrays to write the following with a loop:

cout<<"This variable c1 ="c1
cout<<"This variable c2 ="c2
cout<<"This variable c3 ="c3

for(i=1,i<8,i++)
cout<<"This variable c%d =",i<<**????**<<

This is obviously not what I Need to be done but is the easiest example I could think of with the same problem... So what I would like to do is change the variables in the loop, not the output!

EDIT: Thanks a lot for all the input, here is a bit more of the code to help illustrate my problem...Im Using Cplex with c++. The loop will not end at seven but when a stop criteria is met

static void  populatebyrow (IloModel model, IloNumVarArray x, IloRangeArray c)
{
    IloExpr c1(env);
    IloExpr c2(env);
    IloExpr c3(env);
    IloExpr c4(env);

    c.add(c1>=n);
    c.add(c2>=n); ...

    model.add(c);
}

I Want to add these expressions to an Array called c that will be an input for a model in cplex. Then after I get a result from Cplex I want to add an expression c(i) and solve it again... This until i get the values I want... IloExprArray could also be used somehow, but then I dont know how to add the expressions using this method:

for(i= 0,...)
{
    c7 +=x[i];
}
4
  • 1
    Why would you not use an array? If the variables form a set an array (or other enumerable collection) seems like the correct solution. Commented Jun 9, 2009 at 8:00
  • There's never a need to "change a variable name" in C++, since you can simply create a pointer to any other variable you like. Commented Jun 9, 2009 at 9:47
  • Why don't you generate your source code with a text processor or perl? Commented May 15, 2011 at 9:55
  • Simply with a linked list because you assign new pointers and there for variables adresses dynamically. Commented Dec 28, 2019 at 9:04

8 Answers 8

11

If I understand correctly, you are trying to create variable names dynamically. AFAIK this is not possible with C++.

Sign up to request clarification or add additional context in comments.

2 Comments

I was afraid for that... Thanks anyways
Well he could put a big switch statement in the loop but it's kind of ridiculous
9

I'd recommend using an array for this. You should not be playing with dynamic variable names in a compiled language.

int c[] = {2, 5, 7, 9, 3, 4, 6, 5};
for (int i = 0; i < 8; i++) cout // and so on...

Comments

8
int* varArray[] = {&c1, &c2, &c3};
int size = sizeof( varArray) / sizeof(int*);

for( int i = 0; i < size; ++i)
{
   std::cout << "This variable c"<< i+1 << " = " << *varArray[i] << std::endl;
}

2 Comments

Maybe I'm missing something, but why loop up to 7?
My mistake. It should be the length of the array.
4

If you want to do anything lexically, you're stuck with a macro. Please understand that this is terrible and unmaintainable, but if you insist, you could do something like this:

#define Q(a) a
#define DO_THING(a, expr) do { Q(a)1 expr; Q(a)2 expr; Q(a)3 expr; Q(a)4 expr } while (0)

DO_THING(b, [i] = i);

This results in the code:

do { b1  [i] = i; b2  [i] = i; b3  [i] = i; b4  [i] = i } while (0);

Having written all that out, please please please don't do this. Even if you wrap it in more macros to make it quasi-readable, please please let common sense prevail and abandon this plan.

Comments

2

I have used this function and it works fine:

 IloNumVarArray x(env, 10);

 for(i=0; i<10; i++){
   x[i] = IloNumVar(env, 0, IloInfinity); 

   // Code for change the name of each variable
   char index[2]; 
   sprintf(index, "%d", i); 
   char variable_name[6] = "x"; 
   strcat(variable_name, index); 
   x[i].setName(variable_name);
 }

Comments

1

Well if you really can't go with an array, why not trying with a pointer. I know the following example is essentially an array, however it is slightly different so it may be worth a shot.

#include <iostream>
#include <conio.h>

#define N 10

using namespace std;

int main() {

    int * a = new int[N];

    for (int i = 0, * b = a; i < N; i++, b++) {
        *b = i;    
    }


    for (int i = 0, * b = a; i < N; i++, b++) {
        cout << *b << endl;
    }

    getch();
}

This is still an array, however it is used slightly different and just may be what you are looking for. If it is not, please clarify your question so we may help you. Even if that is the simplest example you can think of, try adding some more detail.

EDIT I just saw (in a comment) you were trying to create variable names dynamically. As far as I know that's not possible, however you may try implementing (or use a library, I'm sure there is plenty out there) a HashMap . Using a hashmap you can link an item to a string (key) so you would be able to link an item to a custom string, entered by the user (assuming that's what you need this for).

Comments

1

Does exploiting or metaprogramming count?

#include <iostream>
template<unsigned U>
struct Fac{ enum { value = U * Fac<U-1>::value};};
template<>
struct Fac<0>{ enum { value = 1};};
template<unsigned U>
struct Fib{ enum {value = (Fib<U-1>::value + Fib<U-2>::value)};};
template<>
struct Fib<0>{ enum {value = 0};};
template<>
struct Fib<1>{ enum {value = 1};};
template<unsigned U>
void show(){
    show<U-1>();
    std::cout << "Fib(" << U << ")=" << Fib<U>::value << "\t" << "Fac(" << U << ")=" << Fac<U>::value << std::endl;
}
template<>
void show<0>(){}

int main(int argc, char** argv){
    show<12>();
}

There is also the possibility to make use of the boost preprocessor extensions, so you can loop a macro to generate identifiers.

Comments

1

here is the way to do that in c/c++ with preprocessor operator ## and macro there are examples of use on this link http://msdn.microsoft.com/en-us/library/09dwwt6y(v=vs.80).aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.