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.

  • 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? – kol Dec 19 '20 at 20:38
  • @kol Yes, everything is the same –  Dec 19 '20 at 20:39
  • Somehow you need to communicate to the compiler that you're calling a function with four arguments or three. – Daniel Walker Dec 19 '20 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. – kol Dec 19 '20 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. https://stackoverflow.com/questions/679979/how-to-make-a-variadic-macro-variable-number-of-arguments – kol Dec 19 '20 at 20:48
  • @kol thanks that is working for me now. –  Dec 19 '20 at 20:52
  • It depends on the use case. When you call `f(a,b,c)` or `g(a,b,c,d)` are `a, b` and `c` the same? And `d` unneeded thus taking a dummy value? – Vorac Dec 20 '20 at 09:06

3 Answers3

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;
}
chomeyama
  • 96
  • 4
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);
    }
}
anotherOne
  • 1,513
  • 11
  • 20
-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 ... }
Narek Daduryan
  • 235
  • 1
  • 5