Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you implement arithmetic operator as variables in C?

I'm trying to program a reverse polish calculator and I didn't wanted to write switches for every single arithmetic operator inputted. Is it possible to input an arithmetic operator and use it as such inside the language itself?

For example, the program could prompt the user for an arithmetic operator, for:
a = b [whatever operator here] c;

and some variable would store the operator. Let's say it's +, we get:
a = b + c;

Is this possible or should I just suck it up and write the switches for the operators?

like image 576
minh anh b Avatar asked Dec 08 '22 09:12

minh anh b


1 Answers

Short answer:

No, it's not possible. At least not the way you want.

Long answer:

No, you cannot. C simply does not support things like the eval function in Python. For those who does not know what it is, this will print "Hello":

s = "print('Hello')" # A string with the code we want to execute
eval(s)              # Evaluate the string s as python code and execute it

If you want to do something like that in C, well just forget it. It's not possible.

You can achieve something similar with function pointers. It will look really awkward if you're not used to function pointers, but it mimics what you're talking about. Although quite badly.

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

// Function taking two int and returning int
typedef int (operation)(int, int);

int main(void) {
    operation *ops[UCHAR_MAX+1];
    ops['+'] = add;
    ops['-'] = sub;
    printf("Sum:  %d\nDiff: %d\n", ops['+'](5,3), ops['-'](5,3));    
}

This prints:

Sum:  8
Diff: 2

ops is an array of function pointers. More precisely, an "array 256 of pointer to function (int, int) returning int". So we're using a single character directly to index it.

One thing to look out for here is to make sure that no negative values are passed to ops. This could happen on a machine where char is signed as default.

If you want some safety in form of error handling, you could do something like this:

int error(int a, int b) {
    fprintf(stderr, "Function not implemented");
    exit(EXIT_FAILURE);
}

and then do:

operation *ops[UCHAR_MAX+1];
for(int i=0; i < sizeof ops/sizeof *ops; i++) 
    ops[i] = error;

ops['+'] = add;
ops['-'] = sub;

This method is not worth all this extra hassle if you only want to support four operations, but it can actually come in quite handy if you're writing an emulator. I watched a very interesting youtube playlist about writing a NES emulator. It's in C++, but very oldschool so if you know C, it's not hard to follow. He talks about function pointers in part 2.

https://youtu.be/F8kx56OZQhg

Note: Not my channel. I have absolutely nothing to do with it. Was hesitating because it could look like spam, but those videos are really interesting for a coder.

like image 61
klutt Avatar answered Dec 28 '22 09:12

klutt