我想知道在C中是否可以创建一个采用不同类型参数的可变函数。即。
void fillDatabase(char* name, int age){
writeToDatabase(name, age);
}
int main(){
fillDatabase("Paul", 19);
fillDatabase("Herbert");
}
这里我试图填写一个包含姓名和年龄的数据库。但它也有可能只用一个名字填充它,没有年龄。所以我想知道我是否可以使用相同的功能,或者我必须写两个不同的功能?
Online我只能找到具有相同类型参数的可变函数的示例。
提前致谢!
答案 0 :(得分:4)
在C99中,可变参数函数使用stdarg(3)操作(通常实现为扩展到编译器特定的神奇内容的宏,例如GCC内置函数)。第一个参数应该有一些固定的已知类型,并且通常确定如何获取其他参数;在今天的几个ABI中,可变参数传递不使用寄存器,因此效率低于固定的arity函数调用。
在你的情况下,你最好有几个功能。对于灵感,sqlite有several open functions。
请注意,POSIX使用一个 last 可选参数定义了一些函数,特别是open(2)。这可能实现为具有不能提供 last 参数的函数。
您可以阅读ABI规范以及特定于您的实施的calling conventions。
顺便说一句,缺乏函数重载(比如在C ++中)可以被理解为C的一个优点(函数名称 - linker唯一关心的事情,至少在Linux和Unix上确定 - 它的签名)。因此C ++实际上需要name mangling。另请阅读dynamic linking和dlopen答案 1 :(得分:0)
查看va_list,va_start等的手册页
使用...序列表示函数原型来表示变量args:
void myfunction(FILE *, *fmt, ...);
例如,我们声明了一个va_list类型的结构(假设你包含了stdarg):
struct va_list l;
使用参数BEFORE初始化列表... - 我们将* 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的手册页。