如何在C中使用可选参数创建函数?

时间:2013-10-06 18:00:03

标签: c function gcc gnu

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

让我清楚地解释一下我的问题。我在这里以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 

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

2 个答案:

答案 0 :(得分: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)(char const *, int, int),所以揭示你的函数实际上接受变量参数没什么意义。 (您可以通过尝试编译类似open("", 1, 2, 3, 4, 5, 6)的内容来测试它。)

答案 1 :(得分:1)

在所有情况下,varargs函数必须能够以某种方式从固定参数中确定有多少变量参数。例如,printf()函数系列使用格式字符串来确定参数的数量和类型。 execl()函数使用sentinel(空指针)来标记参数列表的结尾。有可能使用一个计数而不是一个哨兵(但如果你要这样做,那么非varargs函数中的计数和数组可能会起作用,如果不是更好的话,那么count和参数列表)。 open()函数使用其中一个标志位来确定模式是否存在 - 请参阅Kerrek SBanswer

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

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

或他们的等价物。它也可以接受其他形式;有关一种常见表单,请参阅What's the use of the third environment variable in the C main()?。在C中,但不是C ++,标准编译器可以记录其他返回类型 - 并且Microsoft已将void记录为VS 2008以后的有效返回类型。

因为main()没有实现提供的原型,编译器不能正式拒绝main()的任何声明/定义,尽管它可能会对它无法识别的表单发表评论(GCC)例如,对main()类型的int函数进行评论。