简体   繁体   English

c中具有不同类型参数的可变参数函数

[英]variadic functions with different types of arguments in c

I was wondering if it's possible in C to create a variadic function that takes different types of arguments. 我想知道在C中是否有可能创建采用不同类型参数的可变参数函数。 ie

void fillDatabase(char* name, int age){
  writeToDatabase(name, age);
}

int main(){
  fillDatabase("Paul", 19);
  fillDatabase("Herbert");
}

Here I am trying to fill up a database with names and ages. 在这里,我试图用名称和年龄填充数据库。 But it's also possible to fill it up with only a name and no age. 但是也可以只用一个名字而不用年龄来填充它。 So I am wondering if I could use the same function for that or if I have to write two different ones? 所以我想知道是否可以为此使用相同的函数,或者是否必须编写两个不同的函数?

Online I could only find examples for variadic functions with the same type of arguments. 在网上,我只能找到具有相同参数类型的可变参数的示例。

Thanks in advance! 提前致谢!

In C99, variadic functions use stdarg(3) operations (generally implemented as macros expanding to compiler-specific magical stuff, eg GCC builtins). 在C99中,可变参数函数使用stdarg(3)操作(通常实现为宏,扩展为特定编译器的魔术对象,例如GCC内置函数)。 The first arguments should have some fixed known type, and generally determinates how the other arguments are fetched; 第一个参数应该具有一些固定的已知类型,并且通常确定如何获取其他参数。 in several today's ABIs, variadic function argument passing don't use registers so is less efficient than fixed arity function calls. 在当今的一些ABI中,可变参数函数传递不使用寄存器,因此效率不如固定arity函数调用。

In your case, you'll better have several functions . 就您而言, 最好具有几个功能 For inspiration sqlite has several open functions . 为了获得灵感,sqlite具有几个开放功能

Notice that POSIX defines some function with one last optional argument, in particular open(2) . 注意,POSIX使用最后一个可选参数定义了某个函数,尤其是open(2) This is probably implemented as having a function whose last argument can be not supplied. 这可能实现为具有无法提供其最后一个参数的函数。

You could read the ABI specification and the calling conventions specific to your implementation. 您可以阅读针对您的实现的ABI规范和调用约定

BTW, lack of function overloading (like in C++) can be understood as an advantage of C (the function name -which is the only thing the linker care about, at least on Linux & Unix- determines its signature). 顺便说一句,缺少函数重载(例如在C ++中)可以理解为C的优点(函数名- 链接器唯一关心的事情,至少在Linux和Unix上,这是函数名)。 Hence C++ practically needs name mangling . 因此,C ++实际上需要名称修饰 Read also about dynamic linking and dlopen 另请参阅有关动态链接dlopen的信息

Check the man page for va_list, va_start, etc. 检查手册页中的va_list,va_start等。

You declare your function prototype using the ... sequence to denote variable args: 您可以使用...序列来声明函数原型,以表示变量args:

void myfunction(FILE *, *fmt, ...);

For example, we declatre a struct of type va_list (assuming you included stdarg): 例如,我们声明一个va_list类型的结构(假设您包括了stdarg):

struct va_list l;

Initialise the list using the parameter BEFORE the ... - se we'd pass the *fmt pointer to va_start: 在...之前使用参数初始化列表-我们将* fmt指针传递给va_start:

va_start(l, fmt);

Now, we can call va_arg to get a value...if we're processing a format string we might have a loop something like this: 现在,我们可以调用va_arg来获取一个值...如果我们正在处理格式字符串,则可能会有如下所示的循环:

while (*fmt) {
    /* Look for % format specifier... */
    if (*fmt == '%') {
        /* Following character can be c for char, i for int or f for float. */
        // Opps - advance to char following opening %...
        fmt++;

        if (*fmt == 'c')
            fprintf(stream, "%c", (char) va_arg(l, int));
        else if (*fmt == 'i')
            fprintf(stream, "%i", (int) va_arg(l, int));
        else if (*fmt == 'f')
            fprintf(stream, "%f", (float) va_arg(l, double));
        ... and so on...

You're relying on the character following the % to tell you what data type to expect in the corresponding parameter. 您依靠%后面的字符来告诉您相应参数中期望的数据类型。 Suggest you read the man pages for va_list. 建议您阅读va_list的手册页。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM