帶有可變引數的方法

2021-07-07 05:22:17 字數 1867 閱讀 2392

可變引數:

在看其他人寫的**時看到了這個:

這是個帶可變引數的方法。

有時我們實現乙個方法時不能確定呼叫它時要傳進來幾個引數,多了少了都會產生錯誤,這時可變引數就能體現出他的優點,用三個點代替不確定的引數,呼叫時就可以傳任意個數引數值。

我們先來說一下引數的儲存,函式(方法)引數是以資料結構:棧的形式訪問,從右至左入棧。

首先是引數的記憶體存放格式:引數存放在記憶體的堆疊段中,在執行函式的時候,從最後乙個開始入棧。因此棧底高位址,棧頂低位址,舉個例子如下:

void func(int x, float y, char z);

那麼,呼叫函式的時候,實參 char z 先進棧,然後是 float y,最後是 int x,因此在記憶體中變數的存放次序是 x->y->z,因此,從理論上說,我們只要探測到任意乙個變數的位址,並且知道其他變數的型別,通過指標移位運算,總可以順藤摸瓜找到其他的輸入變數。我們預設把可變引數放在方法引數列表最後,從最後開始入棧,可變引數就在棧底。只要獲取到 … 前面的實參變數的,就可以解析出他代表的所有變數。

使用可變引數時有幾點需要注意:

1、 方法或函式引數列表中不能只有可變引數,至少要有乙個已知實參用來找到引數們的存放位址;

2、 可變引數必須出現在引數列表最後;

3、 可變引數的型別由程式管理;

使用可變引數要了解幾個巨集:

typedef char* va_list;

void va_start ( va_list ap, prev_param );

type va_arg ( va_list ap, type );

void va_end ( va_list ap );

va_list 是乙個字元指標,可以理解為指向當前引數的乙個指標,取參必須通過這個指標進行。

使用步驟如下:

在呼叫參數列之前,定義乙個 va_list 型別的變數,(假設va_list 型別變數被定義為ap);

然後應該對ap 進行初始化,讓它指向可變參數列裡面的第乙個引數,這是通過 va_start 來實現的,va_start是乙個函式,有兩個引數,第乙個引數是 ap 本身,第二個引數是在變參表前面緊挨著的乙個變數,即「…」之前的那個引數;

然後是獲取引數,呼叫va_arg,它的第乙個引數是ap,第二個引數是要獲取的引數的指定型別,然後返回這個指定型別的值,並且把 ap 的位置指向變參表的下乙個變數位置;

獲取所有的引數之後,我們有必要將這個 ap 指標關掉,以免發生危險,方法是呼叫 va_end,他是輸入的引數 ap 置為 null或nil,應該養成獲取完參數列之後關閉指標的習慣。說白了,就是讓我們的程式具有健壯性。通常va_start和va_end是成對出現。

下面是我自己寫的乙個例子:

介面部分:

方法實現部分:

測試程式:

輸出結果:

…中包含了幾個引數,va_arg語句就會迴圈幾次。

如果引數列表忘了加nil或null程式就會死迴圈並且還不會有警告,可在函式或方法宣告後面加巨集定義 ns_requires_nil_termination,忘記加nil時就會出現警告。

劉萌

反射帶有out引數的方法

public int getflag out int result 使用下面的方法來反射 system.type mytype typeof testreflection 反射生成改型別的物件例項 object obj mytype.invokemember null,bindingflags.cr...

方法的可變引數 params

當你寫了乙個方法,這個方法需要對傳進來的引數進行加工,但是不確定傳遞的引數的數量的時候 比如,public void int jiafa int a,int b jiafa 1,2 但是突然需求改了,要傳遞4個引數,那麼就需要改方法。jiafa 1,2,3,4 此時可以使用params public...

可變長引數方法

可變長引數 語法 型別.變數名 只能3個點,不能多也不能少 位置 必須在引數列表的最後 乙個方法最多只能有乙個可變長引數 優先順序 如果有精確匹配得方法則呼叫最精確的那個。特性 可變長引數可以等同看作陣列 定義乙個陣列,可以把陣列當成引數轉進去。public class variablearitym...