stdarg.h简介和使用

 

stdarg.h 简介

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

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

       stdarg.h的主要内容包括

       typedef char *  va_list;

       #define _ADDRESSOF(v)   ( &(v) )
       #define _INTSIZEOF(n)   ( (sizeof(n) +sizeof(int) - 1) & ~(sizeof(int) - 1) )

       #define va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
       #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
       #define va_end(ap)      ( ap = (va_list)0 )
       void va_copy(va_list    dest,  va_list src);

stdarg.h的用法

 存取参数

  存取未命名的参数,首先必须在不定参数函式中宣告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。

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

  使用printf或scanf类的格式化字串来嵌入明确指定的型态。

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

  总数变数来指明不定参数的数量。

  型别安全性

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

实例

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#define LAST 5 //输出的参数的个数
int examplestdary( int t , ... )
{
    va_list ap ;
    va_start( ap , t ) ;
    int i ;
    int tmp = 0 ;
    for( i = 0 ; i < LAST ; i++ )
    {
        tmp = va_arg( ap , int ) ;
        printf( "%d\t" , tmp ) ;
    }
    return 0 ;
}
int main()
{
    examplestdary( 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ) ;
    return 0;
}

小结

       注意整个函数调用流程。首先,定义一个va_list类型的指针;然后va_start()指向最后一个确定的参数;接着,va_art()返回va_list类型指针的下一个元素;最后,va_end()释放指针。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值