「可變引數列表」的學習

2021-07-31 09:45:59 字數 1746 閱讀 7330

最近,學習了「可見引數列表」,忽然之間發現很喜歡它,哈哈~
現在,我們來談談它吧!

功能:可以將函式以可見引數列表的形式實現,使得函式可以接受1個以上的任意多個引數。

應用:要使用可變引數列表,我們要對其原理及用法十分了解!

(1)要引用的標頭檔案被封裝在「stdarg.h「中。

(2)在應用時,首先,宣告乙個 va_list型別的變數 arg ,它用於訪問引數列表的沒有確定的部分,比如幾個變數,什麼型別等。

( 3 ) 初始化,變數arg是呼叫 va_start 來初始化的。它的第乙個引數是 va_list 的變數名,第2個引數是省略號前最後乙個有名字的引數。初始化過程把 arg 變數設定為指向可變引數部分的第乙個引數。

( 4 )引數訪問,為了訪問引數,需要使用 va_arg ,這個巨集接受兩個引數: va_list 變數和引數列表中下乙個引數的型別。

(5)最後,當訪問完畢最後乙個可變引數之後,我們需要呼叫 va_end 結束訪問。

但應用可變引數列表是有限制的,

可變引數的限制:

注意:

(1)可變引數必須從頭到尾逐個訪問。如果訪問了幾個可變引數之後要

終止,這是可以的,但是,不能從一開始就訪問引數列表中間的引數。

(2)引數列表中至少有乙個命名引數。如果連乙個命名引數都沒有,就無法使用va_start。

(3)這些巨集是無法直接判斷實際存在引數的數量,且型別必須指定正確。

(4)這些巨集無法判斷每個引數的型別。

下面舉個例子,用可變引數列表實現函式功能:兩個整數比較大小。

#include

#include//標頭檔案

int max(int n,...) //未知的引數

在發現用可變引數列表實現了個簡單的函式功能時,感覺還是不錯的哇~
下面,轉到原始碼看看:

typedef char *  va_list;

#endif /* _m_cee_pure */

#define _va_list_defined

#endif

#elif defined(_m_ix86)

#define _intsizeof(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

#define _crt_va_start(ap,v) ( ap = (va_list)_addressof(v) + _intsizeof(v) )

#define _crt_va_arg(ap,t) ( *(t *)((ap += _intsizeof(t)) - _intsizeof(t)) )

#define _crt_va_end(ap) ( ap = (va_list)0 )

分析看看:

了解了原始碼的基本的過程,再返回頭看上面寫過的**,理解的會更深入!

可變引數列表

模擬實現printf函式 va list是在c語言中解決變參問題的一組巨集,所在標頭檔案 include 用於獲取不確定個數的引數 va start,函式名稱,讀取可變引數的過程其實就是在堆疊中,使用指標,遍歷堆疊段中的引數列表,從低位址到高位址乙個乙個地把引數內容讀出來的過程 va arg,這個巨...

可變引數列表

小二,上 class a public class varargs two param static void twostringparam string a,string b three param 參照上兩種寫法,一直往後面加。是不是感覺很憂傷 幸好這不是真的。string.a static v...

可變引數列表

測試環境 vs2008 1 可變引數列表 為什麼需要可變引數呢?在函式原型中,列出了函式期望接受的引數,原型只能顯示固定數目的引數,如果函式原型列出的引數與可呼叫引數不匹配或數目不一樣,程式將無法執行。例如,我們想要求一系列值的平均值,這裡的一系列的數目是不確定的,如果這些值儲存於陣列中,這個任務就...