如何定义带参数或不带参数调用的函数? [复制]

Posted

技术标签:

【中文标题】如何定义带参数或不带参数调用的函数? [复制]【英文标题】:How to define function that will called with or without parameters? [duplicate] 【发布时间】:2013-08-19 00:01:23 【问题描述】:

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

char *fnc(???) 

    char *str;
    ....
    return str;

char *c1 = fnc();
char *c2 = fnc(param);

怎么做?

【问题讨论】:

***.com/questions/479207/function-overloading-in-c 如果你使用C++,你可以使用默认参数,声明char *fnc( my_type my_param = my_default )。但是,唉,C 没有这样做。如果他们足够关心的话,这将是对 ANSI C 标准的一个很好的补充。 :) 你们正在放弃 OP 并将他推向 C++。 cboard.cprogramming.com/c-programming/… @Jim 我不会在任何地方“推”任何人。我只是说... ;) 正如其他答案所示,函数重载、可变参数(如printf)和默认参数都是不同的东西。可变参数至少需要一个参数,不满足OP的例子。 没有至少一个参数,什么会告诉你有多少个参数?您的意思是通过全局变量或其他方式进行通信吗? 【参考方案1】:

这叫做Function Overloading你不能用C来做

【讨论】:

默认参数,在C中也不可用。 是的,你可以。请参阅 printf()。 人们实际上会做很多“你不能在 C 中做的事情”,比如 oop =) @Jim,printf 没有重载,它是一个可变参数函数。 你可以用宏实现类似于函数重载的东西【参考方案2】:

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

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

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

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

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

【讨论】:

不,你不需要让真正的函数变参【参考方案3】:

可以使用旧的varargs.h 你有

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() 系列中的格式字符串,或者可能只是一些参数、一些位标志或其他任何东西。

【讨论】:

【参考方案4】:

在 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

【讨论】:

【参考方案5】:

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

void fnc(char* Optional)

    if (Optional != NULL)
    
       // do something amazing
    


fnc(NULL); // "Not passing" a parameter
fnc("hello");

【讨论】:

"我需要用C语言开发一个函数......" 答案在 C 中。唯一不是的部分是“使用 C++ OR【参考方案6】:

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

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

【讨论】:

【参考方案7】:

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

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

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

【讨论】:

printf 和其他可变参数函数至少需要 1 个参数 但你总会有至少一个论据 如果您有一个指定不使用它的标识符,您可以放弃该参数。当您浏览参数列表时,它将位于 switch 语句或 while 循环中。 cboard.cprogramming.com/c-programming/…【参考方案8】:

你可以组合使用:

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*/ 

【讨论】:

【参考方案9】:

在 C++ 中,这很简单:

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

因此,如果您调用不带参数的函数,则函数参数的值将是“default_value”。如果您使用参数调用函数,则函数参数的值将是函数调用中的值。如果你有超过 1 个参数,别忘了把带默认值的参数放在参数列表的最后!

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

【讨论】:

以上是关于如何定义带参数或不带参数调用的函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

c语言宏定义有无参数的区别

构造函数

构造函数

可以像调用带参数的函数一样调用 Groovy 对象吗?

强制 Http Get 接受带参数或不带参数的请求

为啥定义带或不带引号的 JavaScript 对象字面量会有所不同? [复制]