Videos
What are the types of arithmetic operators?
Can arithmetic operators be overloaded in C?
Can arithmetic operators be used with negative numbers in C?
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'+', ops'-');
}
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.
It is possible. See an example below
RPN calculator implies in some sort of stack. On identifying an operand you pop up two operands and does the operation.
I want to let a short example so I will shortcut some things...
our "stack"
I will assume integer operands only, but I think it is not hard to make it generic, by using the usual suspects, void*
This is the stack in the example
// stack
int pop()
{
int val = 1 + rand()%1000 / (-1)*(rand()%2);
printf("pop(): operand %d from stack\n", val);
return val;
}
It just gets a random number in [-998,999] inclusive :)
the operations
// operations
int divd(int A, int B) { return A / B; };
int mult(int A, int B) { return A * B; };
int sub(int A, int B) { return A - B; };
int sum(int A, int B) { return A + B; };
So we have something to test.
the syntax glue
Assuming the operator is a single char we can build a lookup-table indexed by the operator and put the functions there.
C was created precisely to write this kind of things.
int (*the_fs[256])(int,int) = {0};
the_fs['+'] = sum;
the_fs['-'] = sub;
the_fs['*'] = mult;
the_fs['/'] = divd;
a test
// test for some cases
const char oper[] = "+-*/";
const int N = 8;
for (int i = 0; i < N; i += 1)
{
// do one test
int ix = rand() % 4;
printf("using '%c'\n", oper[ix]);
a = pop();
b = pop();
printf("%d %c %d = %d\n", a, oper[ix], b,
the_fs[oper[ix]](a,b));
}
It is just a matter of calling the_fs[X] where X is the operand. No need for if, no need for switch(). It can the used alo for unary operators, just PUSHing back the second operator in the function.
output for a random test with random numbers and random operations
using '+'
pop(): operand -624 from stack
pop(): operand -906 from stack
-624 + -906 = -1530
using '*'
pop(): operand -724 from stack
pop(): operand 1 from stack
-724 * 1 = -724
using '*'
pop(): operand -733 from stack
pop(): operand -807 from stack
-733 * -807 = 591531
using '-'
pop(): operand -938 from stack
pop(): operand 1 from stack
-938 - 1 = -939
using '*'
pop(): operand 0 from stack
pop(): operand -121 from stack
0 * -121 = 0
using '*'
pop(): operand 1 from stack
pop(): operand 1 from stack
1 * 1 = 1
using '-'
pop(): operand 1 from stack
pop(): operand -396 from stack
1 - -396 = 397
using '+'
pop(): operand -130 from stack
pop(): operand -372 from stack
-130 + -372 = -502
the complete test program
#include <stdio.h>
#include <stdlib.h>
int pop(); // stack simulator :)
int sum(int,int);
int sub(int,int);
int mult(int,int);
int divd(int,int);
int main(void)
{
int a = 0;
int b = 0; // the operands
srand(210907);
int (*the_fs[256])(int,int) = {0};
the_fs['+'] = sum;
the_fs['-'] = sub;
the_fs['*'] = mult;
the_fs['/'] = divd;
// so you have an operator, and it is RPN
// the stack must have 2 operands
// test for some cases
const char oper[] = "+-*/";
const int N = 8;
for (int i = 0; i < N; i += 1)
{
// do one test
int ix = rand() % 4;
printf("using '%c'\n", oper[ix]);
a = pop();
b = pop();
printf("%d %c %d = %d\n", a, oper[ix], b,
the_fs[oper[ix]](a,b));
}
return 0;
}
// stack
int pop()
{
int val = 1 + rand()%1000 / (-1)*(rand()%2);
printf("pop(): operand %d from stack\n", val);
return val;
}
// operations
int divd(int A, int B) { return A / B; };
int mult(int A, int B) { return A * B; };
int sub(int A, int B) { return A - B; };
int sum(int A, int B) { return A + B; };
/*
https: //stackoverflow.com/questions/69080130/
can-you-implement-arithmetic-operator-as-variables-in-c
*/