Use a variable to call a function that returns a different variable

First off, I'm a complete noob as I've mentioned in another thread. I've got a couple weeks of experience during which all of my knowledge has come from dissecting and modifying other people's code. For my current question I've been searching the forum and found a lot of posts that have me convinced i need to use pointers to do what I want but it seems that all of those posts deal only with void functions, nothing that actually returns a value of any kind. I (wrongly) assumed that I could simply change "void" to "int" to get my called function to return a value but that results in compiler errors. I don't actually know anything about pointers other than what little bits I've managed to understand from reading other posts.

My application: i'm working on an imu based leveling system but i can't ensure that the imu will be mounted with the Z axis vertical. I'm dealing with this uncertainty by using two inputs driven high or low to tell the program what the imu's orientation is. I could certainly run an IF statement in void loop() to determine the state of the inputs and select the appropriate function. I realize that doing so would take very little processor time or effort but there's just no reason to run that check every time the program loops when i could run the check once at startup, set a variable based on the result, and use that variable to call the necessary function.

I've attached my test sketch below. Any help getting it to work would be greatly appreciated and layman's explanations of how your code is written and why it works would be even better. Thanks all.

int (*myFunc[])(int)={&five, &eighteen, &fortytwo, &eleven};

int val = 0;
int progSelect = 0;
const int switchA = 13;
const int switchB = 12;

void setup() {
  // put your setup code here, to run once:
  pinMode (switchA, INPUT);
  pinMode (switchB, INPUT);
  Serial.begin(9600);
  
  if (switchA == HIGH && switchB == HIGH) {
    progSelect = 0;
  }
  else if (switchA == HIGH && switchB == LOW) {
    progSelect = 1;
  }
  else if (switchA == LOW && switchB == LOW) {
    progSelect = 2;
  }
  else if (switchA == LOW && switchB == HIGH) {
    progSelect = 3;
  }  
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.print(val);
  Serial.println();
  myFunc[progSelect]();
  delay(1000);
}

int five() {
  val = 5;
  return val;
}
int eleven() {
  val = 11;
  return val;
}
int fortytwo() {
  val = 42;
  return val;
}
int eighteen() {
  val = 18;
  return val;
}

For reference the error i'm getting is this: 1:59: error: invalid conversion from 'int ()()' to 'int ()(int)' [-fpermissive]

and

32:22: error: too few arguments to function

int (*myFunc[])(int)={&five, &eighteen, &fortytwo, &eleven};

Your array of function pointers say they point to functions that take a single parameter that is an int.

myFunc[progSelect]();

You call it with no parameters though, so the compiler complains.

Judging by the functions you wrote:

int five() {
  val = 5;
  return val;
}

I would think that the no-parameter version would be the correct one. So lose the int in the parenthesis on the array declaration.

It should also be noted that since val is global, there is no reason to have the function return it. You could just change the value and that change will be visible everywhere.

I would also suggest a different way to write the function. Instead of having different functions to set val to different values, why not one function that takes an int as an argument and sets it.

void setVal(int anInteger){
     val = anInteger;
}

Then you could call:

setVal(5);

instead of five() and you'd only have one function to worry about.

Considering what (I think) your code actually does, I would just have an array filled with the desired values and use the switches to make an index into the array. e.g.

int array[] = {42,11,18,5};
int index = (digitalRead(switchB))<<1) | (digitalRead(switchA));
int value = array[index];

I may not have the array values in the correct order. Rearrange to suit.

Thanks for the responses. I haven’t tried uploading the sketch yet but removing the second int allowed it to compile properly. I didn’t realize that that second part was meant to define parameters being passed to the functions being called.

I should have specified that the code i posted is hugely simplified from what the final version needs to do. It’s only real purpose is to prove the concept and give me some visible proof that the val variable was in fact being modified and returned. In the final version each of the possible called functions will read one axis of the imu, run some calculations, and return the angle of the unit. the idea being that I can save processor cycles by not having to read and calculate all three axis all the time when i only need one depending on the imu’s orientation.

Since you say you're a noob, I thought I should show you something to scare you away from calling functions via indirection:

http://www.newty.de/fpt/fpt.html#arrays

It's a neat trick, but you need a little bit of experience before you should use this, IMHO. But you're the boss.

each of the possible called functions will read one axis of the imu

Since the Cartesian axes are by definition identical, you need only one function, with an appropriate index, to deal with any of the three axes. Similar reasoning applies to any calculation that involves two or more axes.

It is much easier and far less problem prone to use indices rather than arrays of function calls. For example, it is trivial to test that an index is not out of bounds. The only worry is that you must maintain a right-handed coordinate system.