有没有一种方法可以在C语言中指定函数的默认参数?


当前回答

我知道如何更好地做到这一点。 您只需将NULL赋值给一个参数,因此,您将没有值。然后检查参数值是否为NULL,将其更改为默认值。

void func(int x){
if(x == NULL)
  x = 2;
....
}

尽管如此,它还是会引起警告。一个更好的选择是,如果参数值是:

void func(int x){
if(x == 1)
  x = 2;
....
}

在上面的例子中,如果x是1,函数将其更改为2;

感谢@user904963,编辑: 如果必须覆盖所有的数字范围,那么添加另一个参数来告诉函数是否将形参设置为默认并不难

void func(int x, bool useDefault){
if(useDefault) //useDefault == true
  x = 2;
....
}

但是,请记住包含stdboolh

其他回答

哇,这里的每个人都这么悲观。答案是肯定的。

这并不简单:到最后,我们将拥有核心函数、支持结构、包装器函数和宏 围绕包装器函数。在我的工作中,我有一组宏来自动化所有这些;一次 你了解流程,你也会很容易做到。

我已经在其他地方写过了,所以这里有一个详细的外部链接来补充这里的摘要:http://modelingwithdata.org/arch/00000022.htm

我们想转弯

double f(int i, double x)

变成一个接受默认值的函数(i=8, x=3.14)。定义一个伴生结构:

typedef struct {
    int i;
    double x;
} f_args;

将函数重命名为f_base,并定义一个设置默认值和调用的包装器函数 基础:

double var_f(f_args in){
    int i_out = in.i ? in.i : 8;
    double x_out = in.x ? in.x : 3.14;
    return f_base(i_out, x_out);
}

现在添加一个宏,使用C的可变宏。这样用户就不需要知道他们是 实际上填充一个f_args结构体,并认为他们在做通常的事情:

#define f(...) var_f((f_args){__VA_ARGS__});

好了,现在所有下面的都可以工作了:

f(3, 8);      //i=3, x=8
f(.i=1, 2.3); //i=1, x=2.3
f(2);         //i=2, x=3.14
f(.x=9.2);    //i=8, x=9.2

检查复合初始化器如何为确切的规则设置默认值的规则。

有一件事是行不通的:f(0),因为我们无法区分缺失的值和 零。根据我的经验,这是需要注意的事情,但可以作为照顾 这种需求出现了——有一半的情况下,你的违约实际上是零。

我费了这么大劲写出来是因为我认为命名参数和默认值 确实让用C编写代码变得更简单,更有趣。和 C语言太棒了,因为它如此简单,而且仍然有足够的内容使这一切成为可能。

为什么我们不能这样做呢?

给可选参数一个默认值。这样,函数的调用者就不一定需要传递实参的值。参数接受默认值。 很容易,这个参数对客户端来说是可选的。

如。

Void foo(int a, int b = 0);

这里b是可选参数。

一般不会,但在gcc中,你可以使用宏将funcA()的最后一个参数设置为可选的。

在funcB()中,我使用了一个特殊的值(-1)来表示我需要'b'参数的默认值。

#include <stdio.h> 

int funcA( int a, int b, ... ){ return a+b; }
#define funcA( a, ... ) funcA( a, ##__VA_ARGS__, 8 ) 


int funcB( int a, int b ){
  if( b == -1 ) b = 8;
  return a+b;
}

int main(void){
  printf("funcA(1,2): %i\n", funcA(1,2) );
  printf("funcA(1):   %i\n", funcA(1)   );

  printf("funcB(1, 2): %i\n", funcB(1, 2) );
  printf("funcB(1,-1): %i\n", funcB(1,-1) );
}

是的,有了C99的功能,你就可以这样做了。这种工作方式不需要定义新的数据结构,也不需要函数在运行时决定如何调用 没有任何计算开销。

有关详细的解释,请参阅我的帖子

http://gustedt.wordpress.com/2010/06/03/default-arguments-for-c99/

Jens