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


当前回答

不,但你可以考虑使用一组函数(或宏)来近似使用默认参数:

// No default args
int foo3(int a, int b, int c)
{
    return ...;
}

// Default 3rd arg
int foo2(int a, int b)
{
    return foo3(a, b, 0);  // default c
}

// Default 2nd and 3rd args
int foo1(int a)
{
    return foo3(a, 1, 0);  // default b and 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

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;
}

No.

即使是最新的C99标准也不支持这一点。

是的。:-)但不是你所期望的那样。

int f1(int arg1, double arg2, char* name, char *opt);

int f2(int arg1, double arg2, char* name)
{
  return f1(arg1, arg2, name, "Some option");
}

不幸的是,C不允许重载方法,因此最终会得到两个不同的函数。尽管如此,通过调用f2,你实际上是在用默认值调用f1。这是一个“不要重复自己”的解决方案,它可以帮助您避免复制/粘贴现有代码。

我们可以为默认值创建(仅)使用命名形参的函数。这是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