C语言的参数可变函数

环境:fedora12,gcc4.4.4。

C语言参数个数可变的函数,叫做VA函数(variableargumentfunction,例如printf()函数。要实现VA函数需要包含stdarg.h:

#include<stdarg.h>

主要使用下面三个宏定义:
va_start(ap,A)

va_arg(ap,T)

va_end(ap)

ap是类型是va_list,va_list的定义如下:

typedefchar*va_list;

它用来指向函数的参数。

A是函数的最后一个固定参数,一个VA函数必须有至少一个固定参数。

T是参数的类型,例如int,char...,等等。

va_start(ap,A):初始化函数参数指针ap,使ap指向A的右边的第一个参数,即函数可变参数中的第一个;

va_arg(ap,T):返回ap指向的参数的值,参数的类型用T确定,然后将ap指向下一个参数;

va_end(ap):释放ap。

下面的例子定义了一个va函数,作用是依次打印传递给函数的int型参数。

#include <stdio.h> #include <stdarg.h> int va_function(const char *start,...) { int n=1; va_list arg; va_start(arg,start); printf("%s/n",start); while(n != 0) { n=va_arg(arg,int); printf("%d/n",n); } va_end(arg); return 0; } int main(void) { va_function("start",1,2,3,-1,-2,0); return 0; }

注意:

1、VA函数的可变参数类型必须在函数中自行确定,编译器无法自动识别。

2、必须在VA函数中定义可变参数的结束标志,如果没有结束标志,va_arg会依次返回内存中的值,直到访问到非法内存而出错退出。

这几个宏在不同的编译器中有不同的定义,但是功能是一样的,在linux的内核源码中也用定义,可以参考。在内核源码的/include/acpi/platform/acenv.h文件内:

typedef char *va_list;    /* Storage alignment properties */ #define _AUPBND (sizeof (acpi_native_uint) - 1) #define _ADNBND (sizeof (acpi_native_uint) - 1)   /* Variable argument list macro definitions */ #define _bnd(X, bnd) (((sizeof (X)) + (bnd)) & (~(bnd))) #define va_arg(ap, T) (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND)))) #define va_end(ap) (void) 0 #define va_start(ap, A) (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))

参考:

深入浅出VA函数

linuxkernel中的变长参数宏

TheOpenGroupBaseSpecificationsIssue6

<!--EndFragment--> <!--EndFragment-->
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值