可變引數:
在看其他人寫的**時看到了這個:
這是個帶可變引數的方法。
有時我們實現乙個方法時不能確定呼叫它時要傳進來幾個引數,多了少了都會產生錯誤,這時可變引數就能體現出他的優點,用三個點代替不確定的引數,呼叫時就可以傳任意個數引數值。
我們先來說一下引數的儲存,函式(方法)引數是以資料結構:棧的形式訪問,從右至左入棧。
首先是引數的記憶體存放格式:引數存放在記憶體的堆疊段中,在執行函式的時候,從最後乙個開始入棧。因此棧底高位址,棧頂低位址,舉個例子如下:
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...