I am building a library in C and one of the functions that is part of the library is something like:
void myFunction(double *inPtr, double start, double step, double *outPtr, int N, t_shape shape)
{
int i;
switch (shape) {
default:
case ShapeLinear:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) = *(inPtr++) * start;
start += step;
}
/* more stuff going on */
break;
case ShapeExponential:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) = *(inPtr++) * start;
start *= step;
}
/* more stuff going on */
break;
case ShapeSquared:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) = *(inPtr++) * start * start;
start += step;
}
/* more stuff going on */
break;
case ShapeCubed:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) = *(inPtr++) * start * start * start;
start += step;
}
/* more stuff going on */
break;
}
}
This is a simplified version just for the purpose of demonstration.
The actual function in the library has more cases and each case is longer and more complex.
Now I would like to create another version of exactly the same function with the only difference that instead of just assigning a value to outPtr, I would like to add and assign it.
void myFunctionAdd(double *inPtr, double start, double step, double *outPtr, int N, t_shape shape)
{
int i;
switch (shape) {
default:
case ShapeLinear:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) += *(inPtr++) * start;
start += step;
}
/* more stuff going on */
break;
case ShapeExponential:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) += *(inPtr++) * start;
start *= step;
}
/* more stuff going on */
break;
case ShapeSquared:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) += *(inPtr++) * start * start;
start += step;
}
/* more stuff going on */
break;
case ShapeCubed:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) += *(inPtr++) * start * start * start;
start += step;
}
/* more stuff going on */
break;
}
}
As I said, the real function I am working on is longer and more complex so having to rewrite the same code twice is really something I wouldn’t want to do.
It would be bad programming practice and more difficult to maintain.
Is there a C programming technique to deal with this issue?
Could blocks (closures) be useful in this situation?
Do I need to refactor the code somehow?
How would you tackle the problem?
the classic c solution is to pass in a function that gets called to do what you want to vary. This depends however on the basic shape of the operation being the same
ie
typedef int (*func_ptr)(int,int);
myFunction(....... func_ptr do_what)
{
int i;
switch (shape) {
default:
case ShapeLinear:
/* more stuff going on */
for (i = 0; i < N; i++) {
*(outPtr++) = func_ptr(*(inptr++), outPtr);
start += step;
}
/* more stuff going on */
break;
}
int assign(int a, int b)
{
return a;
}
int add_assign(int a, int b)
{
return a + b;
}
then call
myFunction(......assign);
or
myfunction(......add_assign);
this feels a bit forced in your case tho since we have to pass in the old value of outPtr