6

最近在编写文件打开程序时遇到一个问题。

让我清楚地解释我的问题。这里我以open打电话为例。

创建文件:

open("file_name", O_CREAT, 0766); //passing 3 parametrs

打开文件:

open("file_name", O_RDWR); //only 2 arguments.

然后我清楚地观察到了这一点,它也适用main()

main(void) //worked
main(int argc, char **argv); //worked
main(int argc) //worked and it's doesn't give an error like "too few arguments". 
main() //worked 

那么我们如何创建这些可选参数呢?编译器究竟如何验证这些原型?如果可能,请编写一个示例程序。

4

2 回答 2

7

open函数被声明为可变参数函数。它看起来像这样:

#include <stdarg.h>

int open(char const * filename, int flags, ...)
{
    va_list ap;
    va_start(ap, flags);

    if (flags & O_CREAT)
    {
        int mode = va_arg(ap, int);
        // ...
    }

    // ...

    va_end(ap);
}

除非您表明它们确实存在,否则不会使用进一步的参数。

相同的结构用于printf.

手册并不总是明确说明这一点,因为唯一可能的两个签名是(char const *, int)and (char const *, int, int),所以告诉你函数实际上接受可变参数没有什么意义。(您可以通过尝试编译类似的东西来测试它open("", 1, 2, 3, 4, 5, 6)。)

于 2013-10-06T18:05:26.520 回答
1

在所有情况下,可变参数函数必须能够以某种方式从固定参数中确定有多少可变参数。例如,printf()函数族使用格式字符串来确定参数的数量和类型。该execl()函数使用哨兵(空指针)来标记参数列表的结尾。可以使用计数而不是哨兵(但如果您要这样做,则非可变参数函数中的计数和数组可能会与计数和参数列表)。该open()函数使用其中一个标志位来确定模式是否应该存在 - 请参阅Kerrek SB答案

main()函数是一种特殊情况。实现(编译器)禁止为其声明原型,并且必须至少接受两种形式:

int main(int argc, char **argv);
int main(void);

或它们的等价物。它也可以接受其他形式;请参阅C 中第三个环境变量的用途是什么main()对于一种常见的形式。在 C 而不是 C++ 中,标准编译器可以记录其他返回类型——微软已经记录void为从 VS 2008 开始的有效返回类型。

因为没有为 提供实现的原型main(),所以编译器不能正式拒绝 的任何声明/定义main(),尽管它可能会对它不识别的形式传递注释(例如,GCC 会对main()不返回int类型的函数进行注释) )。

于 2013-10-06T18:41:37.237 回答