C语言 具有可变参数的函数,open()是如何工作的?

7nbnzgx9  于 2023-08-03  发布在  其他
关注(0)|答案(5)|浏览(141)

我必须编写一个接受可变数量参数的函数,类似于open()函数

int open (const char *filename, int flags[, mode_t mode])

字符串
1.我看了一下va_list的功能,但是我怎么才能知道用户提供了多少个参数呢?我不想在函数中有一个参数来表明这一点。
1.作为一个新手,我在哪里可以看到open()函数是如何实现的?open()如何知道用户是否提供了 mode 参数?
先谢谢你。

cwtwac6a

cwtwac6a1#

1.你不能这样做。调用者必须提供尾随的sentinel参数(例如a 0),或者显式地告诉函数期望多少个参数(例如printf中的格式字段)。

  1. open知道需要第三个参数,因为您已经在flags参数中设置了O_CREAT标志。
mv1qrgav

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;
 }

字符串

wwwo4jvm

wwwo4jvm3#

你要找的是可变参数函数实现。Here is a doc将引导您完成整个链。

fdbelqdn

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;
}

字符串

avwztpqn

avwztpqn5#

这个问题的简短答案是:“open如何知道它是传递了两个还是三个参数?“是:* 这是魔术 *。答案很长,实现可以做某些你做不到的事情(在标准C语言中)。
另一个例子是main。它有两个有效的原型:

int main(void);

字符串
和/或

int main(int argc, char *argv[]); /* or equivalent */


实现必须允许您使用这两个中的任何一个,并“推断”,这就是您使用的那个。
“我如何在我的代码中做类似的事情?“,是:* 你不能 *,至少不能在C标准所施加的约束之内。

相关问题