fbpx
维基百科

stdarg.h

stdarg.hC語言C標準函式庫標頭檔,stdarg是由standard(標準) arguments(參數)簡化而來,主要目的為讓函式能夠接收不定量參數。[1] C++cstdarg標頭檔中也提供這樣的機能;雖然與C的標頭檔是相容的,但是也有衝突存在。

不定參數函式(Variadic functions)是stdarg.h內容典型的應用,雖然也可以使用在其他由不定參數函式呼叫的函式(例如,vprintf)。

宣告不定參數函式 编辑

不定參數函式的參數數量是可變動的,它使用省略號來忽略之後的參數。例如printf函式一般。代表性的宣告為:

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

不定參數函式最少要有一個命名的參數,所以

char *wrong(...); 

在C是不被允許的。在C,省略符號之前必須要有逗號;在C++,則沒有這種強制要求。 (雖然在C++中,這樣的宣告是合理的,但是這種寫法,因為沒有已命名的參數,使得va_start沒辦法抓到動態參數的正確起始點。)

定義不定參數函式 编辑

使用與聲明時相同的語法來定義:

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 用來保存宏va_arg与宏va_end所需信息 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的实现,提供了对不定参数的扩展,允許編譯器檢查適當的格式化字串及標志(sentinels)的使用。如果沒有這种擴充,編譯器通常無從檢查傳入函式的未命名參數是否為所預期的型態,也不能转换它们为所需要的数据类型。因此,必須小心謹慎以确保正確性,因为不匹配的型態降到导致未定義行為(Undefined behavior)。例如,如果傳递空指针,不能仅仅写入NULL(可能实际定义为0),还要转化为(cast)适当的指针类型。另一个考慮是未命名参数的默认的类型提升。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的機能。MSDN明确指出这一头文件已经过时,完全被stdarg.h取代[2]。這個標頭檔不屬於ISO C的一部分。檔案定義在单一UNIX规范的第二個版本中,簡單的包含所有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因為運作的模式需要舊型態的函式定義。[3]

參見 编辑

參考 编辑

  1. ^ IEEE Std 1003.1 stdarg.h. [2009-07-04]. (原始内容于2009-04-11). 
  2. ^ The macros defined in VARARGS.H are deprecated and exist solely for backwards compatibility. Use the macros defined in STDARGS.H unless you are working with code before the ANSI standard.
  3. ^ 單使用者UNIX系統規範(Single UNIX Specification) varargs.h. [2007-08-01]. (原始内容于2008-06-18). 

stdarg, 是c語言中c標準函式庫的標頭檔, stdarg是由standard, 標準, arguments, 參數, 簡化而來, 主要目的為讓函式能夠接收不定量參數, 的cstdarg標頭檔中也提供這樣的機能, 雖然與c的標頭檔是相容的, 但是也有衝突存在, 不定參數函式, variadic, functions, 是內容典型的應用, 雖然也可以使用在其他由不定參數函式呼叫的函式, 例如, vprintf, 目录, 宣告不定參數函式, 定義不定參數函式, 数据类型, 巨集, 存取參數, 型別安全性, 例子, . stdarg h是C語言中C標準函式庫的標頭檔 stdarg是由standard 標準 arguments 參數 簡化而來 主要目的為讓函式能夠接收不定量參數 1 C 的cstdarg標頭檔中也提供這樣的機能 雖然與C的標頭檔是相容的 但是也有衝突存在 不定參數函式 Variadic functions 是stdarg h內容典型的應用 雖然也可以使用在其他由不定參數函式呼叫的函式 例如 vprintf 目录 1 宣告不定參數函式 2 定義不定參數函式 3 stdarg h数据类型 4 stdarg h巨集 5 存取參數 6 型別安全性 7 例子 8 varargs h 9 參見 10 參考宣告不定參數函式 编辑不定參數函式的參數數量是可變動的 它使用省略號來忽略之後的參數 例如 a href Printf html class mw redirect title Printf printf a 函式一般 代表性的宣告為 int check int a double b 不定參數函式最少要有一個命名的參數 所以 char wrong 在C是不被允許的 在C 省略符號之前必須要有逗號 在C 則沒有這種強制要求 雖然在C 中 這樣的宣告是合理的 但是這種寫法 因為沒有已命名的參數 使得va start沒辦法抓到動態參數的正確起始點 定義不定參數函式 编辑使用與聲明時相同的語法來定義 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 用來保存宏va arg与宏va end所需信息 C89stdarg h巨集 编辑名稱 描述 相容va start 使va list指向起始的參數 C89va arg 檢索參數 C89va end 釋放va list C89va 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 沒有機制定義該怎麼判別傳遞到函式的參數量或者型態 函式通常需要知道或確定它們變化的方法 共通的慣例包含 使用 a href Printf html class mw redirect title Printf printf a 或 a href Scanf html class mw redirect title Scanf scanf a 類的格式化字串來嵌入明確指定的型態 在不定參數最後的標记值 sentinel value 總數變數來指明不定參數的數量 型別安全性 编辑有些C的实现 提供了对不定参数的扩展 允許編譯器檢查適當的格式化字串及標志 sentinels 的使用 如果沒有這种擴充 編譯器通常無從檢查傳入函式的未命名參數是否為所預期的型態 也不能转换它们为所需要的数据类型 因此 必須小心謹慎以确保正確性 因为不匹配的型態降到导致未定義行為 Undefined behavior 例如 如果傳递空指针 不能仅仅写入NULL 可能实际定义为0 还要转化为 cast 适当的指针类型 另一个考慮是未命名参数的默认的类型提升 float將會自動的被轉換成double 同樣的比int 整數 更小容量的參數型態將會被轉換成int或者unsigned int 函式所接收到的未命名參數必須預期将被型態提升 例子 编辑 include lt stdio h gt include lt stdarg h gt 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 1varargs h 编辑POSIX定義所遺留下的標頭檔varargs h 它早在C標準化前就已經開始使用了且提供類似stdarg h的機能 MSDN明确指出这一头文件已经过时 完全被stdarg h取代 2 這個標頭檔不屬於ISO C的一部分 檔案定義在单一UNIX规范的第二個版本中 簡單的包含所有C89 stdarg h的機能 除了 不能使用在標準C較新的形式定義 你可以不給予參數 標準C需要最少一個參數 與標準C運作的方法不同 其中一個寫成 include lt stdarg h gt 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 lt stdarg h gt int summate n int n 以此呼叫 summate 0 summate 1 2 summate 4 9 2 3 2 使用varargs h的函式為 include lt varargs h gt 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因為運作的模式需要舊型態的函式定義 3 參見 编辑可變參數函數參考 编辑 IEEE Std 1003 1 stdarg h 2009 07 04 原始内容存档于2009 04 11 The macros defined in VARARGS H are deprecated and exist solely for backwards compatibility Use the macros defined in STDARGS H unless you are working with code before the ANSI standard 單使用者UNIX系統規範 Single UNIX Specification varargs h 2007 08 01 原始内容存档于2008 06 18 取自 https zh wikipedia org w index php title Stdarg h amp oldid 61985103, 维基百科,wiki,书籍,书籍,图书馆,

文章

,阅读,下载,免费,免费下载,mp3,视频,mp4,3gp, jpg,jpeg,gif,png,图片,音乐,歌曲,电影,书籍,游戏,游戏。