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


当前回答

https://github.com/cindRoberta/C/blob/master/structure/function/default_parameter.c

#include<stdio.h>

void f_impl(int a, float b) {
  printf("%d %g\n", a, b);
}

#define f_impl(...) f_macro(__VA_ARGS__, 3.7)
#define f_macro(a, b, ...) f_impl(a, b)

int main(void) {
  f_impl(1);
  f_impl(1, 2, 3, 4);

  return 0;
}

其他回答

使用宏的另一个技巧:

#include <stdio.h>

#define func(...) FUNC(__VA_ARGS__, 15, 0)
#define FUNC(a, b, ...) func(a, b)

int (func)(int a, int b)
{
    return a + b;
}

int main(void)
{
    printf("%d\n", func(1));
    printf("%d\n", func(1, 2));
    return 0;
}

如果只传递一个参数,则b接收默认值(在本例中为15)

还有一个选项使用结构体:

struct func_opts {
  int    arg1;
  char * arg2;
  int    arg3;
};

void func(int arg, struct func_opts *opts)
{
    int arg1 = 0, arg3 = 0;
    char *arg2 = "Default";
    if(opts)
      {
        if(opts->arg1)
            arg1 = opts->arg1;
        if(opts->arg2)
            arg2 = opts->arg2;
        if(opts->arg3)
            arg3 = opts->arg3;
      }
    // do stuff
}

// call with defaults
func(3, NULL);

// also call with defaults
struct func_opts opts = {0};
func(3, &opts);

// set some arguments
opts.arg3 = 3;
opts.arg2 = "Yes";
func(3, &opts);

我们可以为默认值创建(仅)使用命名形参的函数。这是bk.答案的延续。

#include <stdio.h>                                                               

struct range { int from; int to; int step; };
#define range(...) range((struct range){.from=1,.to=10,.step=1, __VA_ARGS__})   

/* use parentheses to avoid macro subst */             
void (range)(struct range r) {                                                     
    for (int i = r.from; i <= r.to; i += r.step)                                 
        printf("%d ", i);                                                        
    puts("");                                                                    
}                                                                                

int main() {                                                                     
    range();                                                                    
    range(.from=2, .to=4);                                                      
    range(.step=2);                                                             
}    

C99标准定义了初始化中后面的名称覆盖前面的项。我们也可以有一些标准的位置参数,只是相应地改变宏和函数的签名。默认值参数只能在命名参数样式中使用。

项目输出:

1 2 3 4 5 6 7 8 9 10 
2 3 4 
1 3 5 7 9

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

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

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

Jens