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()釋放指針。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章