我必须编写一个接受可变数量参数的函数,类似于open()函数
int open (const char *filename, int flags[, mode_t mode])
字符串1.我看了一下va_list的功能,但是我怎么才能知道用户提供了多少个参数呢?我不想在函数中有一个参数来表明这一点。1.作为一个新手,我在哪里可以看到open()函数是如何实现的?open()如何知道用户是否提供了 mode 参数?先谢谢你。
cwtwac6a1#
1.你不能这样做。调用者必须提供尾随的sentinel参数(例如a 0),或者显式地告诉函数期望多少个参数(例如printf中的格式字段)。
0
printf
open
flags
O_CREAT
mv1qrgav2#
直接从GCC页面复制。下面是一个完整的示例函数,它接受可变数量的参数。该函数的第一个参数是剩余参数的计数,将这些参数相加并返回结果。虽然这个函数很简单,但它足以说明如何使用可变参数功能。
#include <stdarg.h> #include <stdio.h> int add_em_up (int count,...) { va_list ap; int i, sum; va_start (ap, count); /* Initialize the argument list. */ sum = 0; for (i = 0; i < count; i++) sum += va_arg (ap, int); /* Get the next argument value. */ va_end (ap); /* Clean up. */ return sum; } int main (void) { /* This call prints 16. */ printf ("%d\n", add_em_up (3, 5, 5, 6)); /* This call prints 55. */ printf ("%d\n", add_em_up (10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); return 0; }
字符串
wwwo4jvm3#
你要找的是可变参数函数实现。Here is a doc将引导您完成整个链。
fdbelqdn4#
它使用O_CREAT。我从内核6.1.0-9-amd 64的源代码中找到了实现:
static __attribute__((unused)) int open(const char *path, int flags, ...) { mode_t mode = 0; int ret; if (flags & O_CREAT) { va_list args; va_start(args, flags); mode = va_arg(args, mode_t); va_end(args); } ret = sys_open(path, flags, mode); if (ret < 0) { SET_ERRNO(-ret); ret = -1; } return ret; }
avwztpqn5#
这个问题的简短答案是:“open如何知道它是传递了两个还是三个参数?“是:* 这是魔术 *。答案很长,实现可以做某些你做不到的事情(在标准C语言中)。另一个例子是main。它有两个有效的原型:
main
int main(void);
字符串和/或
int main(int argc, char *argv[]); /* or equivalent */
型实现必须允许您使用这两个中的任何一个,并“推断”,这就是您使用的那个。“我如何在我的代码中做类似的事情?“,是:* 你不能 *,至少不能在C标准所施加的约束之内。
5条答案
按热度按时间cwtwac6a1#
1.你不能这样做。调用者必须提供尾随的sentinel参数(例如a
0
),或者显式地告诉函数期望多少个参数(例如printf
中的格式字段)。open
知道需要第三个参数,因为您已经在flags
参数中设置了O_CREAT
标志。mv1qrgav2#
直接从GCC页面复制。
下面是一个完整的示例函数,它接受可变数量的参数。该函数的第一个参数是剩余参数的计数,将这些参数相加并返回结果。虽然这个函数很简单,但它足以说明如何使用可变参数功能。
字符串
wwwo4jvm3#
你要找的是可变参数函数实现。Here is a doc将引导您完成整个链。
fdbelqdn4#
它使用O_CREAT。
我从内核6.1.0-9-amd 64的源代码中找到了实现:
字符串
avwztpqn5#
这个问题的简短答案是:“
open
如何知道它是传递了两个还是三个参数?“是:* 这是魔术 *。答案很长,实现可以做某些你做不到的事情(在标准C语言中)。另一个例子是
main
。它有两个有效的原型:字符串
和/或
型
实现必须允许您使用这两个中的任何一个,并“推断”,这就是您使用的那个。
“我如何在我的代码中做类似的事情?“,是:* 你不能 *,至少不能在C标准所施加的约束之内。