6

可能重复:
C/C++:传递可变数量的参数

按函数声明方式

return-type function-name(parameter-list, ...) {body ...}

下面的代码是一种重载吗?

(在 A_FILE.h 中)

typedef VOID *FUNCTION(UINTN Number, ...);

似乎我可以只将一个Number参数或多个参数传递给FUNCTION函数,那么参数的数量是否取决于函数的实现?

4

3 回答 3

3

函数声明中的省略号意味着它将接受许多参数,否则在运行时未知的变量参数,通过使用标准头文件stdarg.h,该头文件'stdarg.h'中的各个函数可以确定什么每个可变参数都构成传递给函数的参数。

考虑这个代码示例:

#define PANIC_BUF_LEN 256
void panic(const char *fmt, ...){
    char buf[PANIC_BUF_LEN];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(errcode);
}

典型的调用可以是示例之一:

panic("Error: %s failed! Due to unknown error, message is '%s'\n", "my_function", "Disk not ready");

将以这种方式在控制台上产生输出:

Error: my_function failed! Due to unknown error, message is 'Disk not ready'

请注意函数的用法,va_start(...)更不用说va_end(...)提供vsprintf(...)的“未知”参数中填充空白了,这些参数被初始化为指向在运行时未知的变量参数 va_list

编辑:只是为了强调,调用假定C 字符串格式形式的字符串参数小于PANIC_BUF_LEN上面示例中表示的最大大小,除了挑剔之外,这是为了说明函数如何接受使用的标准 C 格式字符串的数量,例如,可以%d在字符串格式中指定一个,并期望 aint与参数匹配。

于 2012-12-27T03:55:23.527 回答
2

它不是 C++ 意义上的重载,但它可以用于类似的效果。表示该...函数在命名参数之后接受任意数量的附加参数(必须至少有一个命名参数),并且附加参数可以具有任何类型(某种)。1 此类函数的实现必须能够在运行时推断其附加参数的数量和类型。例如,printf可以一次打印任何内置类型和任意数量的东西,但您必须以%与实际参数相对应的格式字符串为其提供代码。

用于模拟 C++ 风格重载的变量参数的一个值得注意的例子是open系统调用,在 C++ 术语中它有两个重载:

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

并且手册页是这样写的,但是如果您查看一下,<fcntl.h>您会发现实际的声明是

int open(const char *, int, ...);

如果在标志中设置了该位,则该实现仅查看第三个参数O_CREAT,并且记录了如果设置该位,则必须提供第三个参数。与 C 语言中的往常一样,如果你做错了,编译器会高兴地看着它在运行时对你造成影响。

1由于称为“默认参数提升”的残留语言功能,当作为附加参数传递给采用可变数量参数的函数时,一些数字类型会变成其他更大的数字类型。如果您正在编写此类函数的主体,您只需要担心这一点。

于 2012-12-27T04:20:45.820 回答
0

不,“...”表示可变参数。

重载是当编译器混合名称以产生具有不同参数集的多个函数时。在 C 中,函数名称不会混合,但函数可以接受 1 个或多个参数。

于 2012-12-27T03:59:16.743 回答