3
void f(int a, char b, char* c) {
    if(..) {
        ...
        f(a,b,c); //recursive
    }
    ...
}
void g(int a, double b, char* c, int d) {
    if(..) {
        ...
        g(a,b,c,d); //recursive
    }
    ...
}

I want to make a separate function because I use the code within the if statement several times. But this function have to have a function as a parameter becuase I use recursive method. I know that we can use function as a parameters, but in the f function there are 3 parameters, in the g function have 4 parameters.

The code in the if statement in f is the same as the code in the if of g. Except for the function call in that code?

Simply I have no idea how to solve this issue.

7
  • 1
    Do you mean the code in the if statement in f is the same as the code in the if of g? Except for the function call in that code? Commented Dec 19, 2020 at 20:38
  • @kol Yes, everything is the same Commented Dec 19, 2020 at 20:39
  • Somehow you need to communicate to the compiler that you're calling a function with four arguments or three. Commented Dec 19, 2020 at 20:39
  • 1
    You could create two functions: one that contains the part of the code before the function call, and another that contains the part after it. Commented Dec 19, 2020 at 20:41
  • 1
    You could also create a macro with variable number of arguments, where the function to be called (f or g) and its parameters (a, b, c or a, b, c, d) are given last to the macro, after the other parameters required by the code of the if statement. stackoverflow.com/questions/679979/… Commented Dec 19, 2020 at 20:48

3 Answers 3

3

You can use union to pack the variable number of arguments, as shown in sample code below. It may be unusual to use union like this, but it works.

#include<stdio.h>

union u {
  struct { int a; char   b; char* c;        } f;
  struct { int a; double b; char* c; int d; } g;
};

void func_u_f (union u* ua) {
  printf("  f = {a: %d, b: %c, c:%s}\n", ua->f.a, ua->f.b, ua->f.c);
  ua->f.a++;
}

void func_u_g (union u* ua) {
  printf("  g = {a: %d, b: %e, c:%s, d:%d}\n",
         ua->g.a, ua->g.b, ua->g.c, ua->g.d);
  ua->g.a++; ua->g.b *= 2.0; ua->g.d++;
}

void r (int i, void (*func) (union u*), union u* ua) {
  if (i < 3) { /* or whatever conditions to terminate recursion */
    printf ("Recursion %d\n", i);
    func(ua);
    r (++i, func, ua);
  } else {
    printf ("Exit recursion at %d\n", i);
    return;
  }
}

int main () {
  union u u1, u2;

  /* f */
  u1.f.a = 10; u1.f.b = 'X'; u1.f.c = "I am u.f.";
  r(0, &func_u_f, &u1);
  /* g */
  u2.g.a = 10; u2.g.b = .4e-6; u2.g.c = "I am u.g."; u2.g.d = 98;
  r(-2, &func_u_g, &u2);

  return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

1

I am proposing you an easy fix that doesn't work in general because it involves the use of a sentinel value.

Let's say that the the variable d that you pass to g is always positive. Than you can choose -1 as sentinel value.

You always pass four parameters to the function myIf and then check whether d is -1. If it is, then you call f with three parameters, otherwise you call g.

int main() {

    myIf(a, b, c, d);

    return 0;
}

void myIf(int a, int b, char *c, int d)
{
    if( d == -1 ) {
        
        f(a, b, c);
    }
    else {
        
        g(a, b, c, d);
    }
}

2 Comments

How does this compile? Or is it intended as pseudo code?
Yeah it doesn't compile. It's just to help visualize the concept.
-2

I'm not sure exactly what you're trying to do. But if you're worried about code duplication in the if statements, you can refactor that our to another function:

if (isCondition()) ...

bool isCondition() { return ... }

1 Comment

It's not just the condition that's the same. The OP wants to pass in the function to call as a parameter.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.