`
jakielong
  • 浏览: 223278 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

stdarg.h

阅读更多

 

stdarg.h是C语言中C标准函数库的头文件,stdarg是由stdandard(标准) arguments(参数)简化而来,主要目的为让函数能够接收不定量参数。 C++的cstdarg头文件中也提供这样的机能;虽然与C的头文件是兼容的,但是也有冲突存在。

不定参数函数(Variadic functions)是stdarg.h内容典型的应用,虽然也可以使用在其他由不定参数函数调用的函数(例如,vprintf)。

 

声明不定参数函数

 

不定参数函数的参数数量是可变动的,它使用省略号来忽略之后的参数。例如printf函数一般。代表性的声明为:

int check(int a, double b, ...);

不定参数函数最少要有一个命名的参数,所以

char *wrong(...);

在C是不被允许的(在C++中,这样的声明是合理的)。在C,省略符号之前必须要有逗号;在C++,则没有这种强制要求。

 

定义不定参数函数

 

使用相同的语法来定义:

long func(char, double, int, ...);
 
long func(char a, double b, int c, ...)
{
    /* ... */
}

在旧形式可能会出现较省略的函数定义:

long func();
 
long func(a, b, c, ...)
    char a;
    double b;
{
    /* ... */
}

 

stdarg.h型态

名称描述  兼容
va_list    用来指向参数    C89

 

 

 

stdarg.h

名称描述兼容
va_start 使va_list指向起始的参数 C89
va_arg 检索参数 C89
va_end 释放va_list C89
va_copy 拷贝va_list的内容 C99

访问参数

访问未命名的参数,首先必须在不定参数函数中声明va_list型态的变数。调用va_start并传入两个参数:第一个参数为va_list型态的变数,第二个为函数最后一个参数的名称,接着每一调用va_arg就会回传下一个参数,va_arg的第一个参数为va_list,第二个参数为回传的型态。最后va_end必须在函数回传前被va_list呼叫(當作參數)。(沒有要求要讀取完所有參數)

C99提供額外的巨集,va_copy,它能够复制va_list。而va_copy(va2, va1)意思为拷贝va1va2

没有机制定义该怎么判别传递到函数的参数量或者型态。函数通常需要知道或确定它们变化的方法。共通的惯例包含:

  • 使用printfscanf类的格式化字符串来嵌入明确指定的型态。

  • 在不定参数最后的标兵值(sentinel value)。

  • 总数变数来指明不定参数的数量.  

 

 

类型安全性

 

 

有些C工具将C扩充允许编译器检查适当格式化字符串及标兵(sentinels)的使用。如果没有这个扩充,编译器通常无从检查传入函数的未命名参数是否为所预期的型态。因此,必须对点做出谨慎的正确性确认,型态没有吻合为未定义行为(Undefined behavior)。举个例,如果传入NULL指针,首先就是不能写入对应到适当指针型态但纯粹NULL的指针。再者考虑默认参数应用到未命名参数。float将会自动的被转换成double‧同样的比int(整数)更小容量的参数型态将会被转换成int或者unsigned int‧函数所接收到的未命名参数必须预期到会被转换型态。

 

例子

 

#include <stdio.h>
#include <stdarg.h>
 
void printargs(int arg1, ...) /* 输出所有int型态的参数,直到-1結束 */
{
  va_list ap;
  int i;
 
  va_start(ap, arg1); 
  for (i = arg1; i != -1; i = va_arg(ap, int))
    printf("%d ", i);
  va_end(ap);
  putchar('\n');
}
 
int main(void)
{
   printargs(5, 2, 14, 84, 97, 15, 24, 48, -1);
   printargs(84, 51, -1);
   printargs(-1);
   printargs(1, -1);
   return 0;
}

 这个程序产生输出:

 

5 2 14 84 97 15 24 48
84 51

1

varargs.h

 

POSIX定义所遗留下的头文件varargs.h,它早在C标准化前就已经开始使用了且提供类似stdarg.h的机能。这个头文件不属于ISO C的一部分。文件定义在单用户UNIX系统规范(Single UNIX Specification)的第二个版本中,简单的包含所有C89 stdarg.h的机能,除了:不能使用在标准C较新的形式定义;你可以不给予参数(标准C需要最少一个参数);与标准C运作的方法不同,其中一个写成:

 

#include <stdarg.h>
 
int summate(int n, ...)
{
    va_list ap;
    int i = 0;
 
    va_start(ap, n);
    for (; n; n--)
        i += va_arg(ap, int);
    va_end(ap);
    return i;
}

 或比较旧式的定义:

 

#include <stdarg.h>
 
int summate(n, ...)
    int n;
{
    /* ... */
}
 以此调用
summate(0);
summate(1, 2);
summate(4, 9, 2, 3, 2);


使用
varargs.h的函数为:

 

#include <varargs.h>
 
summate(n, va_alist)
    va_dcl /* 这里沒有分号! */
{
    va_list ap;
    int i = 0;
 
    va_start(ap);
    for (; n; n--)
        i += va_arg(ap, int);
    va_end(ap);
    return i;
}
 以及相同的调用方法。

varargs.h因为运作的模式需要旧型态的函数定义。



 

 

分享到:
评论

相关推荐

    可变参数stdarg.h使用方法(例题)

    可变参数stdarg.h使用方法(例题) va_list用法 va_start已经 va_end

    stdarg.h中三个宏va_start ,va_arg和va_end的应用

    1)首先在函数里定义一个va_list型的变量,这里是arg_ptr,这个变 量是指向参数的指针. 2)然后用va_start宏初始化变量arg_ptr,这个宏的第二个参数是第 一个可变参数的前一个参数,是一个固定的参数. ...

    _mingw_stdarg.h

    _mingw_stdarg.h

    c语言基于stdarg.h的可变参数函数的用法

    本篇文章主要介绍了c语言基于stdarg.h的可变参数函数的用法,详细的介绍了可变参数函数的详细用法和源码实例,有兴趣的可以了解一下

    C标准库文档,包括标准库中12个头文件的描述

    * &lt;stdarg.h&gt; : Variable Argument Lists * &lt;stddef.h&gt; : Definitions of General Use * &lt;stdio.h&gt; : Input and Output * &lt;stdlib.h&gt; : Utility functions * &lt;string.h&gt; : String functions * &lt;time.h&gt; : Time...

    linux头文件介绍

    linux应用程序中常用头文件的介绍 ; &lt;assert.h&gt; 验证程序断言 &lt;cpio.h &gt; cpio归档值 ...&lt;stdarg.h &gt; 可变参数表 &lt;stddef.h &gt; 标准定义 &lt;stdio.h &gt; 标准I/O库 &lt;stdlib.h &gt; 公用函数 &lt;string.h &gt; 字符串操作 ......

    C语言头文件大全

    ISO C标准定义的头文件(24项) &lt;assert.h&gt; 验证程序断言 &lt;complex.h&gt; 支持复数算术运算 &lt;ctype.h&gt; 字符类型 &lt;errno.h&gt; 出错码 ...&lt;signal.h&gt; 信号 &lt;stdarg.h&gt; 可变参数表 &lt;stdbool.h&gt; 布尔类型和值

    C_Standar_Library

    • &lt;stdarg.h&gt; : Variable Argument Lists • &lt;stddef.h&gt; : Definitions of General Use • &lt;stdio.h&gt; : Input and Output • &lt;stdlib.h&gt; : Utility functions • &lt;string.h&gt; : String functions • &lt;time.h&gt; : Time...

    C语言函数库详解.doc

    C语言函数库详解.doc C语言函数库,包含 C 标准库、IO 函数、字符处理函数、...9. &lt;stdarg.h&gt;:可变参数表 10. &lt;stddef.h&gt;:公共定义 11. &lt;stdio.h&gt;:输入输出 12. &lt;stdlib.h&gt;:实用函数 13. &lt;time.h&gt;:日期与时间函数

    C标准库函数集.rar

    7 变长变元表 &lt;stdarg.h&gt; 44 8 非局部跳转 &lt;setjmp.h&gt; . . . . . . . . . . 45 9 信号处理 &lt;signal.h&gt; . . . . . 46 10 日期与时间函数 &lt;time.h&gt; . . . . 48 11 由实现定义的限制 &lt;limits.h&gt; 和 &lt;float.h&gt; . . ....

    计算器课程设计c语言版

    #include &lt;stdarg.h&gt; /*变量长度参数表*/ #include &lt;graphics.h&gt; /*图形函数*/ #include &lt;string.h&gt; /*字符串函数*/ #include &lt;ctype.h&gt; /*字符操作函数*/ #define UP 0x48 /*光标上移键*/ #define DOWN 0x50 /...

    stdarg的用法(可变参数的用法)

    可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头文件,它是标准库的一部分。 这个头文件声明的一个va_list的类型,和三个宏va_start,va_arg,va_end。我们可以生明一个va_list类型的变量,配合三个宏使用。...

    C语言基础教程TXT

    7.8.7 随机数发生器函数 ...B.7 变量变元表:&lt;stdarg.h&gt; B.8 非局部跳转:&lt;setjmp.h&gt; B.9 信号处理:&lt;signal.h&gt; B.10 日期与时间函数:&lt;time.h&gt; B.11 由实现定义的限制:&lt;limits.h&gt;和 &lt;float.h&gt; 附录C 变更小结

    strsafe.rar

    3个版本的strsafe.h strsafe.h specstrings.h stdarg.h strsafe.lib

    带中文注释的 linux 0.11 源代码

    .....\.......\stdarg.h .....\.......\stddef.h .....\.......\string.h .....\.......\sys .....\.......\...\stat.h .....\.......\...\times.h .....\.......\...\types.h .....\.......\...\utsname.h ...

    嵌入式微控制器 的轻量级日志记录_C语言_代码_相关文件_下载

    uLog 是具有最小依赖性的“积极独立”,仅需要 stdio.h、string.h 和 stdarg.h。 当你不使用 uLog 时,它不会妨碍你:如果 ULOG_ENABLED 在编译时未定义,则不会生成日志记录代码。 uLog 已经过很好的测试。有关详细...

    The C programming Language(chm格式完整版)

    Variable Argument Lists: &lt;stdarg.h&gt; Non-local Jumps: &lt;setjmp.h&gt; Signals: &lt;signal.h&gt; Date and Time Functions: &lt;time.h&gt; Implementation-defined Limits: &lt;limits.h&gt; and &lt;float.h&gt; Appendix C: Summary ...

    STM32F103C8T6标准库-printf重定向

    #include &lt;stdarg.h&gt; int fputc(int ch, FILE* stream) { // 将ch输出到你想要的设备或接口 return ch; } ``` 2. 在main函数中使用以下代码,将stdout流重定向到上述的fputc函数: ``` int main(void) { // 其他...

Global site tag (gtag.js) - Google Analytics