C/C++中的变量函数和参数赋值

Riz*_*izo 5 c c++ arguments function

我想知道在C/C++语言中是否可以以键值形式将参数传递给函数.例如在python中你可以这样做:

def some_function(arg0 = "default_value", arg1):
    # (...)

value1 = "passed_value"
some_function(arg1 = value1)
Run Code Online (Sandbox Code Playgroud)

所以C中的替代代码可能如下所示:

void some_function(char *arg0 = "default_value", char *arg1)
{
    ;
}

int main()
{
    char *value1 = "passed_value";
    some_function(arg1 = value1);
    return(0);
}
Run Code Online (Sandbox Code Playgroud)

所以在some_function中使用的参数是:

arg0 ="default_value"

arg1 ="pass_value"

有任何想法吗?

Chr*_*oph 8

这是使用复合文字和可变参数宏的C99解决方案:

#include <stdio.h>

#define some_func(...) some_func_((struct some_func_args_){ __VA_ARGS__ })

struct some_func_args_
{
    const char *arg1;
    const char *arg2;
};

static void some_func_(struct some_func_args_ args)
{
    if(!args.arg1) args.arg1 = "default";
    printf("---\narg1 = %s\narg2 = %s\n", args.arg1, args.arg2);
}

int main(void)
{
    some_func("foo", "bar");
    some_func(.arg1 = "spam");
    some_func(.arg2 = "eggs");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,使用此方法无法区分零/ NULL参数和省略的参数. (3认同)

sel*_*tze 6

您可以使用以下方法在C++中模拟它:

struct params {
   string foo_;
   double bar_;
   short  xxx_;
   params() : foo_("123"), bar_(3.1415), xxx_(42) {} // default parameters
   params& foo(string s) {foo_=s;return *this;}
   params& bar(double x) {bar_=x;return *this;}
   params& xxx(short x) {xxx_=x;return *this;}
};

void some_function(params const & p);

int main() {
   some_function(params().bar(99.9).xxx(23));
}
Run Code Online (Sandbox Code Playgroud)

但恕我直言,这不值得努力.锅炉板太多了.

如果我没记错的话,Stroustrup的书"C++的设计和演变"包含了一个讨论"命名参数"的这个特征请求的部分.结论类似于:不是一个好主意.如果您需要详细信息,请查看它.


el.*_*ado 6

C中不支持命名参数,但您可以使用variadic函数模拟命名参数(尽管您松散了类型安全性):

#include <stdarg.h>

void do_sth (int foo, ...)
{
    int baz = 7;             /* "baz" argument */
    const char *xyz = "xyz"; /* "xyz" argument */

    /* Parse named parameters */
    va_list ap;
    va_start (ap, foo);
    for (;;) {
        const char *key = va_arg (ap, char *);
        if (key == NULL) {
            /* Terminator */
            break;
        } else if (strcmp (key, "baz") == 0) {
            baz = va_arg (ap, int);
        } else if (strcmp (key, "xyz") == 0) {
            xyz = va_arg (ap, char *);
        } else {
            /* Handle error */
        }
    }
    va_end (ap);

    /* do something useful */
}

do_sth (1, NULL);                             // no named parameters
do_sth (2, "baz", 12, NULL);                  // baz = 12
do_sth (3, "xyz", "foobaz", NULL);            // xyz = "foobaz"
do_sth (4, "baz", 12, "xyz", "foobaz", NULL); // baz = 12, xyz = "foobaz"
Run Code Online (Sandbox Code Playgroud)

只记得用NULL结束可选参数列表.您也可以使用一些ENUM作为键而不是字符串.

在GTK +中,此技术用于exacmle: