1

我需要在 C 中开发一个函数,该函数将使用相同的定义调用,带或不带参数,如下所示:

char *fnc(???) 
{
    char *str;
    ....
    return str;
}
char *c1 = fnc();
char *c2 = fnc(param);

怎么做?

4

9 回答 9

3

这被称为函数重载你不能在 C 中做到这一点

于 2013-08-16T14:31:14.487 回答
2

您无法在 C 中完全实现您想要的。

您确实有一些可用的选项:

  • 将您的函数声明为 varargs 函数并使用 va_ 宏来访问可选参数(请注意,在这种情况下,您需要至少有一个固定 - 非可选 - 参数,并且您还需要知道剩余参数的类型你通过了)

  • 使用可变参数宏定义来包装函数名称并根据需要调用实际函数 - 您仍然需要使真正的函数可变参数,但可变参数宏不需要首先使用固定参数。

如果其中任何一个听起来有帮助,我可以举例说明。

于 2013-08-16T14:50:43.750 回答
2

可以使用旧的varargs.h There you have

void varfunc( va_alist )
va_dcl
{
     va_list args;
     char    *p1;

     va_start( args );
     p1 = va_arg( args, char * );  /* any type is possible */
     ...
     va_end( args );
}

使用现代stdarg.h,这是不可能的了。您可以使用可变参数定义函数,但您必须始终按原样固定一个:

void varfunc( int fixedArg, ... )  // of course fixedArg can be of any type 
{
     va_list  args;
     char     *p1;


     va_start( args, fixedArg );  // here you need the fixed one
     p1 = va_arg( args, char * ); // again any type i possible
     ...
     va_end( args );
}

没有固定参数的语法没有意义有一个非常明显的原因:由于没有可移植的方法来确定已传递的参数数量和类型,因此您需要在固定参数中提供该信息,例如系列中的格式字符串,printf()或者可能只是一些参数,一些位标志或其他。

于 2013-08-16T14:51:52.613 回答
1

使用C++而不是C,或传递一个NULL指针:

void fnc(char* Optional)
{
    if (Optional != NULL)
    {
       // do something amazing
    }
}

fnc(NULL); // "Not passing" a parameter
fnc("hello");
于 2013-08-16T14:31:32.310 回答
1

在 C 中你不能直接这样做,你必须通过一个宏。可变参数宏不同于可变参数函数,因为它们允许参数为空。然后你必须检测参数是否实际上是空的,并为最终的函数调用提供一个默认参数。

我有一个宏包P99可以为你完成所有的包装工作。一种可能性是声明类似

#define fnc(...) P99_CALL_DEFARG(fnc_imp, 1, __VA_ARGS__)
#define fnc_defarg_0() (char const*)0

void fnc_imp(char const* arg) {
  if (!arg) {
    /* do something special */
  }
  /* your code */
}

请注意,在 C 中,宏可能与函数具有相同的名称,如果您不觉得这令人困惑,那么您甚至可以命名函数本身fnc

于 2013-08-16T16:19:03.570 回答
1

解决问题的正确方法是首先认识到您不应该将一个函数用于两种不同的情况;因为这几乎没有意义,并且会产生代码维护问题(例如,很难检测到“错误数量的参数”错误)。

例如,您可以有一个foo_simple(void)(内部)调用foo_complex(arg1, arg2);其他代码可以使用任何让他们开心的功能。

于 2013-08-16T20:49:46.560 回答
0

这里似乎有很多被误导的答案。你想要的就像 printf,它可以带 0 个参数,也可以带多个参数。为了模仿这一点,您在函数中使用 ... 说明符。

 function variableArguments(void * typeDefinition, ...);

您可以通过传入非指针值的地址将 void * 转换为您想要的任何内容,即使它不是指针。

于 2013-08-16T14:36:42.413 回答
0

您可以结合使用以下内容:

1:

#define function() function(NULL)
void function(void * parameter)
{
    if (parameter != NULL)
    { /*code*/ }
}

2:

void function(void * parameter)
{
    if (parameter != NULL)
    { /*code*/ }
}
call: func(NULL); or func(ptr);

3:

use a va_list

4:

我不确定C是否处理这个问题,但你/也许/能够使用默认参数

void function(void * parameter = NULL)
{
     if (parameter != NULL)
     { /*code*/ }
}
于 2013-08-16T15:29:07.327 回答
0

在 C++ 中,这很容易:

char *fnc(parameter=default_value){
....
}

因此,如果您调用不带参数的函数,则函数参数的值将是“default_value”。如果您使用参数调用函数,则函数参数的值将是函数调用中的值。如果您有多个参数,请不要忘记将具有默认值的参数放在参数列表的末尾!

顺便说一句,对不起我的英语不好,如果我错了,请告诉我。我是一名编程学徒 :-)

于 2013-08-16T19:04:07.543 回答