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

variadic functions with different types of arguments in c

我想知道是否可以在 C 中创建一个接受不同类型参数的可变参数函数。即

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

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

我在这里尝试用姓名和年龄填充数据库。但也可以只填写姓名而不填写年龄。所以我想知道我是否可以为此使用相同的功能,或者我是否必须编写两个不同的功能?

Online 我只能找到具有相同参数类型的可变参数函数的示例。

提前致谢!

在 C99 中,可变参数函数使用 stdarg(3) 操作(通常实现为宏扩展到 编译器特定的 神奇的东西,例如 GCC 内置函数)。第一个参数应该有一些固定的已知类型,并且通常决定如何获取其他参数;在当今的几个 ABI 中,可变函数参数传递不使用寄存器,因此效率低于固定元数函数调用。

在你的情况下,你最好有几个函数。对于灵感,sqlite 有 several open functions.

请注意 POSIX 定义了一些带有一个 last 可选参数的函数,特别是 open(2)。这可能实现为具有无法提供 last 参数的函数。

您可以阅读针对您的实施的 ABI specification and the calling conventions

顺便说一句,没有函数重载(就像在 C++ 中一样)可以理解为 C 的一个优点(函数名——这是唯一 linker care about, at least on Linux & Unix- determines its signature). Hence C++ practically needs name mangling. Read also about dynamic linking and dlopen

查看 va_list、va_start 等的手册页

您使用 ... 序列声明函数原型以表示变量 args:

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

例如,我们声明了一个 va_list 类型的结构(假设您包含了 stdarg):

struct va_list l;

在...之前使用参数初始化列表 - 我们会将 *fmt 指针传递给 va_start:

va_start(l, fmt);

现在,我们可以调用 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...

您依靠 % 后面的字符来告诉您相应参数中期望的数据类型。建议您阅读 va_list.

的手册页