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


当前回答

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

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

其他回答

不,那是c++语言的特性。

OpenCV使用的是:

/* in the header file */

#ifdef __cplusplus
    /* in case the compiler is a C++ compiler */
    #define DEFAULT_VALUE(value) = value
#else
    /* otherwise, C compiler, do nothing */
    #define DEFAULT_VALUE(value)
#endif

void window_set_size(unsigned int width  DEFAULT_VALUE(640),
                     unsigned int height DEFAULT_VALUE(400));

如果用户不知道他应该写什么,这个技巧会很有用:

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

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

我已经在其他地方写过了,所以这里有一个详细的外部链接来补充这里的摘要: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语言太棒了,因为它如此简单,而且仍然有足够的内容使这一切成为可能。

使用宏的另一个技巧:

#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)

简单的回答:不。

稍微长一点的回答:有一个很老很老的解决方法,你传递一个字符串来解析可选参数:

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

哪里的opt可能包括“name=value”对或其他东西,你会叫喜欢吗

n = f(2,3.0,"foo","plot=yes save=no");

显然,这只是偶尔有用。一般来说,当你想要一个单一的接口到一系列功能时。


你仍然可以在专业程序用c++编写的粒子物理代码中找到这种方法(例如ROOT)。它的主要优点是可以几乎无限期地扩展,同时保持向后兼容性。