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


当前回答

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

其他回答

做到这一点的最好方法(根据你的情况,这可能也可能不可能)可能是转移到c++,并将其作为“更好的C”使用。你可以在不使用类、模板、操作符重载或其他高级特性的情况下使用c++。

这将为您提供一个具有函数重载和默认参数(以及您选择使用的任何其他特性)的C变体。如果你真的想只使用c++的一个受限子集,你就必须稍微自律一些。

很多人会说以这种方式使用c++是一个糟糕的想法,他们可能是有道理的。但这只是一种观点;我认为使用c++中你觉得舒服的特性是合理的,而不必购买整个东西。我认为c++成功的一个重要原因是它在早期被大量的程序员以这种方式使用。

不是真的。唯一的方法是编写一个varargs函数,并手动填充调用者没有传递的参数的默认值。

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

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

如。

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

这里b是可选参数。

是的,你可以做一些类似的事情,在这里你必须知道你可以得到的不同的参数列表,但你有相同的函数来处理。

typedef enum { my_input_set1 = 0, my_input_set2, my_input_set3} INPUT_SET;

typedef struct{
    INPUT_SET type;
    char* text;
} input_set1;

typedef struct{
    INPUT_SET type;
    char* text;
    int var;
} input_set2;

typedef struct{
    INPUT_SET type;
    int text;
} input_set3;

typedef union
{
    INPUT_SET type;
    input_set1 set1;
    input_set2 set2;
    input_set3 set3;
} MY_INPUT;

void my_func(MY_INPUT input)
{
    switch(input.type)
    {
        case my_input_set1:
        break;
        case my_input_set2:
        break;
        case my_input_set3:
        break;
        default:
        // unknown input
        break;
    }
}

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

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

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

Jens