stdarg.h
是C语言中C标准函数库的头文件,stdarg是由stdandard(标准) arguments(参数)简化而来,主要目的为让函数能够接收不定量参数。 C++的cstdarg
头文件中也提供这样的机能;虽然与C的头文件是兼容的,但是也有冲突存在。
不定参数函数(Variadic functions)是stdarg.h
内容典型的应用,虽然也可以使用在其他由不定参数函数调用的函数(例如,vprintf
)。
声明不定参数函数
不定参数函数的参数数量是可变动的,它使用省略号来忽略之后的参数。例如printf
函数一般。代表性的声明为:
int check(int a, double b, ...);
不定参数函数最少要有一个命名的参数,所以
在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)
意思为拷贝va1
到va2
。
没有机制定义该怎么判别传递到函数的参数量或者型态。函数通常需要知道或确定它们变化的方法。共通的惯例包含:
类型安全性
有些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使用方法(例题) va_list用法 va_start已经 va_end
### stdarg.h中三个宏va_start,va_arg和va_end的应用详解 在C语言中,经常需要编写能够接受可变数量参数的函数。一个典型的例子就是`printf`函数,它可以接受任意数量和类型的参数。为了支持这种功能,C语言提供了...
_mingw_stdarg.h
c的头文件stdio.h
C语言基于stdarg.h的可变参数函数的用法 在C语言中,函数的参数个数通常是在函数声明时指定的,但是在某些情况下,我们需要使用可变参数函数,即函数的参数个数可以根据实际情况而定。这种函数的实现是基于stdarg.h...
* <stdarg.h> : Variable Argument Lists * <stddef.h> : Definitions of General Use * <stdio.h> : Input and Output * <stdlib.h> : Utility functions * <string.h> : String functions * <time.h> : Time...
linux应用程序中常用头文件的介绍 ; <assert.h> 验证程序断言 <cpio.h > cpio归档值 ...<stdarg.h > 可变参数表 <stddef.h > 标准定义 <stdio.h > 标准I/O库 <stdlib.h > 公用函数 <string.h > 字符串操作 ......
7 变长变元表 <stdarg.h> 44 8 非局部跳转 <setjmp.h> . . . . . . . . . . 45 9 信号处理 <signal.h> . . . . . 46 10 日期与时间函数 <time.h> . . . . 48 11 由实现定义的限制 <limits.h> 和 <float.h> . . ....
程序员在使用变长参数函数时,应该包含stdarg.h头文件,并在函数中定义一个va_list类型的变量,然后使用这些宏来实现对不定数量参数的访问。 变长参数函数为C语言提供了类似于C++函数重载的功能,但是它们之间存在...
可变参数列表是通过宏来实现的,这些宏定义于stdarg.h头文件,它是标准库的一部分。 这个头文件声明的一个va_list的类型,和三个宏va_start,va_arg,va_end。我们可以生明一个va_list类型的变量,配合三个宏使用。...
这些头文件包括:<assert.h>、<ctype.h>、<errno.h>、<limits.h>、<locale.h>、<math.h>、<setjmp.h>、<signal.h>、<stdarg.h>、<stddef.h>、<stdio.h>、<stdlib.h>、<time.h>等。 每个头文件都提供了不同的函数,...
7.8.7 随机数发生器函数 ...B.7 变量变元表:<stdarg.h> B.8 非局部跳转:<setjmp.h> B.9 信号处理:<signal.h> B.10 日期与时间函数:<time.h> B.11 由实现定义的限制:<limits.h>和 <float.h> 附录C 变更小结
stdarg.h头文件提供了一个宏定义va_list,用于定义变量参数列表。 7. stddef.h - 标准定义头文件 stddef.h头文件提供了多个宏定义,例如NULL、offsetof、ptrdiff_t、size_t、wchar_t等,用于定义标准的数据类型...
本文档主要介绍了单片机C语言中常用的头文件,包括assert.h、ctype.h、float.h、limits.h、math.h、stdarg.h、stddef.h、stdio.h、stdlib.h和string.h等。这些头文件提供了各种函数和宏定义,帮助开发者更方便地进行...
在我们的压缩包文件中,包含了三个关键的文件:`strsafe.h`,`specstrings.h`,以及`stdarg.h`,还有`strsafe.lib`库文件。这些文件构成了Strsafe函数库的核心部分,下面我们来详细探讨它们的作用和重要性。 首先,...
这一特性主要通过标准库中的 `<stdarg.h>` 头文件来实现。`<stdarg.h>` 提供了一些宏和数据类型,使得程序员能够在不知道确切参数数量的情况下处理函数调用。 `printf` 函数是最典型的使用可变参数的例子,其原型...
C51可变参数函数允许程序员设计能接受不定数量参数的函数,这在C语言中是通过头文件stdarg.h提供的宏实现的。stdarg.h在Keil C51环境中也提供了对可变参数函数的支持,可以让嵌入式开发人员灵活地编写函数,以处理...