1

So I am trying to make a program that does math operations based on user input, however I am running into an issue with trying to set the math operator based on what they give.

Function:

const operator(int val)
{
    if (val == 1)
    {
    return +;
    }
    if (val == 2)
    {
    return -;
    }
}

With a main code looking something like this

scanf("%d", val)
output = 4 operator(val) 2
printf("%d", output)

Is there a variable type that I can use in place of an operator? If not is there a way to make a variable/function reference a defined macro?

For example:

#define plus +

then reference the macro in the code?

Finally I am aware I could have if cases for each input, however this scales poorly for something like,

output = 2 operator(val) 5 operator(val) 7 operator(val) 3 

which would require 64 if statements I think to make it work.

Thank you for reading, I am at my wits end on this.

Warior4356
  • 27
  • 5
  • 5
    You can't to this in C. `#define plus +` don't do this kind of nonsense, it makes your program hard to read. – Jabberwocky Nov 17 '16 at 08:06
  • @MichaelWalz Can you elaborate on this? Is there a way to do the math functions with out massive amounts of if statements? – Warior4356 Nov 17 '16 at 08:07
  • 1
    You could take a string and parse it to find the operator in between the operands. – George Nov 17 '16 at 08:07
  • @George Can you offer an example? I am not sure what you mean. – Warior4356 Nov 17 '16 at 08:08
  • 1
    This sounds like an [XY Problem](http://xyproblem.info/). What are you __actually__ trying to achieve? – Jabberwocky Nov 17 '16 at 08:08
  • Do you want the user to be able to type e.g. "30+20-5" and the program then prints "45" ? – Jabberwocky Nov 17 '16 at 08:10
  • 1
    So you are trying to make a kind of calculator? Then you have two choices really: One is to read the values separately, then read the operator (either input like `'+'` or a value from a menu), and finally use the operator to select the operation though a `switch` of `if` statement. The second choice is to *parse* actual expressions, which is much harder. – Some programmer dude Nov 17 '16 at 08:11
  • @MichaelWalz I am trying to generate and solve random math problems, and I am trying to avoid writing 64 if statements to deal with all permutations with only 3 operators. I was stating it as user input as that seemed simpler to deal with than rand statements. – Warior4356 Nov 17 '16 at 08:11
  • 1
    And whichever way you go you don't need to handle permutations by doubling the number of statements. Loops and functions are your friends. – Some programmer dude Nov 17 '16 at 08:12
  • @Someprogrammerdude Thats more or less correct I want to have a function define the variables and also the operators to find the solution. How exactly would I "read" the operator? I could not figure out how to make a variable work as an operator with the types I tried. – Warior4356 Nov 17 '16 at 08:14
  • Maybe [this SO](http://stackoverflow.com/questions/28256/equation-expression-parser-with-precedence) question may help, but beware what you are trying to do is not really for beginners. – Jabberwocky Nov 17 '16 at 08:15
  • 2
    [return function instead of operator](http://ideone.com/IQgTxT) – BLUEPIXY Nov 17 '16 at 08:17
  • @BLUEPIXY That is perfect thank you. Could you explain what you are doing if you dont mind, I dont like copy pasting code I dont understand – Warior4356 Nov 17 '16 at 08:24
  • [Probably the simplest calculator possible in C](http://ideone.com/cHvY6H). Expand as needed. If you want something that can handle "real" expressions then search for *expression parsing in c* or similar. Read about parsers, there's a lot of theory and plenty of examples. Search for *operator precedence parser*. Continue searching, read the tens of thousands of sources available on the Internet. – Some programmer dude Nov 17 '16 at 08:25
  • @BLUEPIXY Good.... as you make your bed, so you must lie on it... ;) – LPs Nov 17 '16 at 08:25
  • @Warior4356 It is not very useful when computing from expression strings. There are many examples on this site to analyze expressions and produce results. – BLUEPIXY Nov 17 '16 at 08:27
  • @BLUEPIXY my goal is not expression strings, its solving randomly generated math problems, your answer works fine, though something similar was posted as an answer below. The only thing I am still stuck on is using integers and getting remainders out when doing division. – Warior4356 Nov 17 '16 at 08:38
  • `return a % b;` – BLUEPIXY Nov 17 '16 at 08:49
  • @BLUEPIXY The shoe finally dropped that this cant handle order of operations. Thanks for the help and this will work for all single operation statements but I am going to need to do something as MichaelWalz suggested to make this work for more than one. – Warior4356 Nov 17 '16 at 08:58
  • It is not clear that you want. – BLUEPIXY Nov 17 '16 at 09:13
  • `output = 2 operator(val) 5 operator(val) 7 operator(val) 3` can write `output = fold(operator(val), (int[]){2, 5, 7, 3}, 4);` [demo](http://ideone.com/IQgTxT) – BLUEPIXY Nov 17 '16 at 09:34

1 Answers1

5

What you can do is using function pointers.

Lets say you are restricting yourself to integers and add / subtract for this example:

int add(int a, int b)
{
    return a + b;
}

int subtract(int a, int b)
{
    return a - b;
}

// without typedef, the signature of get_operator would be really messy
typedef int (*arithmetic_func)(int,int);

arithmetic_func get_operator(int val)
{
    if (val == 1)
    {
        return &add;
    }
    if (val == 2)
    {
        return &subtract;
    }
    return NULL; // what to do if no function matches?
}

Instead of output = 4 operator(val) 2 you can write:

output = get_operator(val)(4, 2)

What happens there is, that the get_operator(val) function call is returning a function pointer to an actual arithmetic function. Then this actual arithmetic function is called with the (4, 2) as parameters.

grek40
  • 13,113
  • 1
  • 24
  • 50
  • 2
    For the love of obfuscation, use a typedef. Maybe then you'll be able to post an answer with valid C code that actually compiles. Hint: `int (*get_operator(int val))(int, int)`. But don't write crap like that, use a typedef. – Lundin Nov 17 '16 at 08:33
  • Also note that [both `return add;` and `return &add;` will work](/questions/16917043/do-function-pointers-need-an-ampersand), with the difference being that one will match your coding style and the other won't. –  Nov 17 '16 at 08:34
  • This is really helpful and solves all but one case, what do I do about division? If I wanted the result in the form Num R Remainder, i.e. if the problem is 5 / 3, then the answer should be provided as 1 R 2. How would I format int divide() to do this? – Warior4356 Nov 17 '16 at 08:34
  • @Lundin yea, sorry. Screwed up in this part. Should be fixed now. – grek40 Nov 17 '16 at 08:39
  • @Warior4356 I think you should separate the concerns of division result and division remainder. Returning both things with the same operator would lead to a bulk of follow-up questions (like what is the result of adding the results of two divisions?). – grek40 Nov 17 '16 at 08:58