You can't so easily since C does not support them. The simpler way to get "fake overloading" is using suffixes as already said... default values could be simulated using variable arguments function, specifying the number of args passed in, and programmatically giving default to missing one, e.g.:
aType aFunction(int nargs, ...)
{
// "initialization" code and vars
switch(nargs)
{
case 0:
// all to default values... e.g.
aVar1 = 5; // ...
break;
case 1:
aVar1 = va_arg(arglist, int); //...
// initialize aVar2, 3, ... to defaults...
break;
// ...
}
}
Also overloading can be simulated using var args with extra informations to be added and passed and extracode... basically reproducing a minimalist object oriented runtime ...
Another solution (or indeed the same but with different approach) could be using tags: each argument is a pair argument type + argument (an union on the whole set of possible argument type), there's a special terminator tag (no need to specify how many args you're passing), and of course you always need "collaboration" from the function you're calling, i.e. it must contain extra code to parse the tags and choose the actual function to be done (it behaves like a sort of dispatcher)