Variable value to variable name ...

I'd like to use the value of a variable to construct the name of another variable. For example, say I'm passing a string to a routine, I'd like to use that string as part of another variable:

char strVar = "foo";
routine(strVar);

Then in the actual routine, I want to construct a variable name based on what was just passed:

void routine(char myVar) {
long test_myVar = 0; // this should then translate to the variable name 'test_foo' since myVar == "foo" ...

Is this even possible?

Is this even possible?

No.
That is why god invented arrays.

Grumpy_Mike:
That is why god invented arrays.

Would that imply that a woman is simply a subset of a man's array? grin

But ... how would I refer to an array item as a variable name?

Basically, I'm passing a value to a routine. Based on that value, the routine uses one or another variable to store and/or retrieve data. Those variables are already predefined, it's just a matter of figuring out which to use.

Basically, I'm passing a value to a routine. Based on that value, the routine uses one or another variable to store and/or retrieve data. Those variables are already predefined, it's just a matter of figuring out which to use.

The value that you pass would be used as an index into the array. If the value is non-numeric, you'll need to somehow map it to a numeric value. On a PC, a map (a collection of name,value pairs) would be used.

On the Arduino, you really don't have room for a map or the code to create/access one. Much better to just pass a numeric value.

Or if you MUST do this, I suggest you to use hash function.

KirAsh4:
I'd like to use the value of a variable to construct the name of another variable. For example, say I'm passing a string to a routine, I'd like to use that string as part of another variable:

char strVar = "foo";

routine(strVar);



Then in the actual routine, I want to construct a variable name based on what was just passed:

void routine(char myVar) {
long test_myVar = 0; // this should then translate to the variable name 'test_foo' since myVar == "foo" ...


Is this even possible?

Apart from the syntactic problems - you are passing an array of char, but receiving a single char, this would be totally fraught with problems.

Imagine for a moment:

void routine(char a) {
long relay_delay = 0;

Do you really want "relay_delay" to become "relfooy_delfooy"? I think not.

Based on that value, the routine uses one or another variable to store and/or retrieve data. Those variables are already predefined, it's just a matter of figuring out which to use.

Perhaps if you described the real problem, not what your attempted solution would be?

You could look up the STL "map" type, but I think this is unlikely to be required.

Nick, I don't know how else to explain it. This isn't a real problem versus a not-so-real problem situation. It is what it is.

I have two variables:

long chicken_abc[8];
long chicken_def[8];

Then I have a routine 'chicken_legs()' that gets called like so:

chicken_legs('abc');
OR:
chicken_legs('def');

Based on that, within the 'chicken_legs()' routine, I need to figure out which variable to use based on what was passed. Now, I can do it with an IF THEN ELSE statement:

// assume for the sake of this exercise that DATA = what was passed to the routine
if DATA == 'abc'
  do something with chicken_abc;
else
  do something with chicken_def;

The problem with that approach is that as the values that can get passed to the routine get larger (in quantity, not length), the IF THEN ELSE routine (or SWITCH CASE) would get rather long as well.

So, what I'm wondering is, if there's a way to not have to use that method, and simply do:

// assume for the sake of this exercise that DATA = what was passed to the routine
use chicken_DATA; // where DATA gets substituted for whatever it contains, be it 'abc' or 'def' or anything else.

There are ways to do this with other languages, so I'm curious whether it can be done here as well.

KirAsh4:
It is what it is.

Isn't everything?

KirAsh4:
I have two variables:

long chicken_abc[8];

long chicken_def[8];




Then I have a routine 'chicken_legs()' that gets called like so:

chicken_legs('abc');
OR:
chicken_legs('def');




Based on that, within the 'chicken_legs()' routine, I need to figure out which variable to use based on what was passed. 

...

There are ways to do this with other languages, so I'm curious whether it can be done here as well.

Yes, well you are thinking of interpreted languages, like Lua, Perl etc. Those languages process the source at runtime, or otherwise give access to the compiler symbol table. For example, in Lua you could that by constructing a string value to key into the global environment table, thus accessing any global variable by a name computed at run time.

However C++ doesn't work like that. The code uploaded to the processor has no memory of the variable names used to generate it, and thus no mechanism for accessing different variables by name.

Now you can achieve the end result (it isn't totally clear what that is, you are giving examples of how you want to achieve something, not what the something is).

I think personally that passing strings down to functions and using them as selectors is a bit slow and unwieldy on a microprocessor. Any objection to passing numbers?

Judging by the way you are writing your code, you are a bit new to C++. Rather than trying to fight it and make variable names that are computed at runtime, I would read up a bit more on what the language offers. No insult intended, but sometimes people who are new to a language try to do things in it that are better suited to other languages.

This isn't a real problem versus a not-so-real problem situation.

The "real" problem isn't to change the way you access variables at run-time, right? The real problem is to control a robot, or a heating system, or make an access-control system, or fly a rocket to the moon (etc.). Perhaps if you explain what you want to achieve (leaving the language aside for one minute) we could offer more useful advice.

A memory killing solution of your question could be an if then else ladder or a switch case

void routine(char *s)
{
  if (strcmp(s, "abc") ==0) var_abc = 0; break;
  if (strcmp(s, "def") ==0) var_def = 0; break;
  if (strcmp(s, "ghi") ==0) var_ghi = 0; break;
  if (strcmp(s, "jkl") ==0) var_jkl = 0; break;
  // ad infinitum 
}

As PaulS points out, it can be simplified with array’s.

// two arrays with same index belong to each other
char array[5][] ={ "abc", def", "ghi", "jkl" };
int var[5];

void routine(char *s)
{
  for (int i= 0; i< SOMESIZE; i++)
  {
     if (strcmp(s, array[i]) ==0) 
     {
       var[i] = 0; 
       return;
     }
  }
}

The Object Oriented view would bring the string and the int together in a struct or a class and make an array of that. That is left as an exercise for the reader :wink:

Are you trying to accomplish something that can’t be done by simply passing the parameters as pointers or references:

char strVar = "foo";
routine(strVar);

void routine(char myVar) {
long test_myVar = 0; // this should then translate to the variable name 'test_foo' since myVar == "foo"

How about this:

long myVarA;
long myVarB;

routine(&myVarA);
routine(&myVarB);

void routine(long *myVar)
{
    *myVar = 0;
}

Something like this might be what you’re looking for:

#define NUM_COMMANDS  3

//Declare a basic struct type that contains our command string and function pointer
struct funcLookup{
  char name[10];
  void (*function)(int);
};

//Declare our lookup table
//define our command names and pointers to associated function
//note that command names do not have to be anything like the function name
funcLookup funcTable[NUM_COMMANDS] = {
  {"func1", &func1},
  {"func2", &func2},
  {"func3", &func3}
};

void setup(){
  
  Serial.begin(115200);
  
  //example calling function based on text input using lookup table
  char funcName[] = "func2";
  callFunc(funcName, 10);
  
  //Iterate through our function table
  for(int i = 0; i < NUM_COMMANDS; i++)
  {
    funcTable[i].function(i);
  }
  
}

void loop(){
  
  
}


//This function walks through our lookup table for the passed in command
//Then calls it's associated function
void callFunc(char* funcName, int val){
  for(int i = 0; i < NUM_COMMANDS; i++){
    if(strcmp(funcName, funcTable[i].name) == 0){
      funcTable[i].function(val);
      return;
    }
  }
  
  //If we reach here, the command did not exist
  //Can report unknown command if wanted
}

void func1(int val){
  Serial.println("Function 1");
  Serial.println(val);
}

void func2(int val){
  Serial.println("Function 2");
  Serial.println(val);
}

void func3(int val){
  Serial.println("Function 3");
  Serial.println(val);
}

It was originally presented as a sort of command interpreter, but may be applicable to what you are trying to accomplish.

Just keep in mind that the strings in the table will all be stored in RAM. With some modifications they could be moved to progmem to eliminate that concern. Maybe I’ll work on that modification at some point in the future…

After doing some more reading, it seems doing what I was thinking would be easy, is actually not exactly as easy nor worth the trouble considering memory usage and what not. Yes, I do come from a Lua-like environment, so I find myself thinking like that 90% of the time. Having rewritten the routine now, I'm just passing INTs and using arrays and it's happy as can be. But thanks to Nick especially, and everyone who followed with code examples for getting me on the right track.

Now I have another question related to hex values ... but I will put that in a different post.