【问题标题】:Functions with variable arguments. How does open() work?具有可变参数的函数。 open() 是如何工作的?
【发布时间】:2011-09-23 19:49:25
【问题描述】:

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

int open (const char *filename, int flags[, mode_t mode])
  1. 我查看了 va_list 功能,但我如何才能知道用户提供了多少参数?我不想在函数中有一个参数来表明这一点。

  2. 作为一个新手,我在哪里可以查看 open() 函数是如何实现的? open() 如何知道用户是否提供了 mode 参数?

提前致谢。

【问题讨论】:

    标签: c linux


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:
      1. 你不能。调用者必须提供一个尾随标记参数(例如 0),或者明确告诉函数期望多少个参数(例如 printf 中的格式字段)。

      2. open 知道期待第三个参数,因为您将在 flags 参数中设置 O_CREAT 标志。

      【讨论】:

        【解决方案3】:

        直接从GCC page复制。

        这是一个完整的示例函数,它接受可变数量的参数。该函数的第一个参数是剩余参数的计数,它们相加并返回结果。虽然微不足道,但这个函数足以说明如何使用可变参数工具。

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

        【讨论】:

        • 这里,count 表示用户提供了多少个参数。那是我不想要的。如果您看到 open() 函数,则没有 count 参数。
        • 我认为重点是open 不接受任何参数来指定是否传递了第三个参数。所以,你的例子没有回答这个问题。
        • 不幸的是你不能。您必须以某种方式包含调用中有多少额外参数的信息。
        • open() 函数是如何工作的,因为用户无法说出有多少额外参数。另外,如果你在 open() 中读取 mode 参数的值,你怎么知道它是用户提供的,而不是一些随机值?
        • @horizo​​n_06 open 知道,因为您在标志中指定了 O_CREAT。如果您: 指定 O_CREAT 并且不提供 3. 参数,open() 将不知道,您将获得未定义的行为。
        【解决方案4】:

        对问题的简短回答“open 如何知道它是否传递了两个或三个参数?”是:这很神奇。长答案是允许实现做某些你不能做的事情(即在标准 C 中)。

        另一个例子是main。它有两个有效的原型:

        int main(void);
        

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

        实现必须允许您使用两者中的任何一个,并“推断”,这是您使用的那个。

        “我怎样才能在我的代码中做类似的事情?”这个问题的答案是:你不能,至少在 C 标准强加的约束范围内是这样。 p>

        【讨论】:

        • Oli Charlesworth 的答案是我一直在寻找的,所以基本上,要么包括一个尾随的标记值,要么明确说明预期有多少参数。
        • -1: open不是魔法。它只是使用标志来确定预期的结果。
        • @Oli: open 并不神奇,但open 的实现,它允许向它传递两个或三个参数是“神奇的”,在某种意义上它可以' t 在标准 C 中完成。如果它不是“魔术”,则可以在 standard C 中编写类似open 的函数(采用 2 或 3 个参数)。
        • @Alok:当然有可能!如果设置了特定标志,则查找第三个参数。
        • @Oli: 换句话说,你能不能在标准 C 中写一个函数add(),根据第一个数字是否为负,添加 2 个或 3 个数字传递给它?所以,我应该可以打电话给add(1, 2, 3); 得到6,和add(-1, 5); 得到4?请注意,我必须能够使用不同数量的参数调用add()
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多