c 函式中變化的引數用『...』 表示。變化的引數依舊按照c函式傳參的規則入棧,即從右往左依次入棧,保證引數從左往右位址依次公升高。
解析變參的主要思想是:將變參緩衝區像容納了不同型別的陣列(當然實際的陣列裡的變數型別不可能是不同的)一樣對待。獲取變參緩衝區首位址,按已知型別進行強轉取值,跳過該值,取出下乙個值,取完為止。
但是這裡有涉及幾個問題:
1,如何知道變參緩衝區的首位址?
2,強轉時如何知道該引數的型別?
4,何時結束解析過程,即如何知道變參的個數?
下面依次解答上面的問題:
首先先看一段**(摘自微軟vadefs.h):
#elif defined(_m_ix86)首先應該明確棧中資料成員均按int型位元組對齊。棧中的定址均按int型位元組進行。有了這個約定我們就能解決上面4個問題中最關鍵的兩個問題1,3。#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 )
...typedef char * va_list;
#ifdef __cplusplus
#define _addressof(v) ( &reinterpret_cast(v) )
#else
#define _addressof(v) ( &(v) )
#endif
...#define va_start _crt_va_start
#define va_arg _crt_va_arg
#define va_end _crt_va_end
**中 _intsizeof(n) 計算出n所佔位元組是int位元組數的倍數(向上取整)。
_crt_va_start(a,v) 給出變參緩衝區的首位址,等於與第乙個變參左側第乙個形參的位址加上該形參位元組對齊後應佔的位元組數。
相信看到這裡,已經知道該怎麼變參了。
至於如何知道引數個數,和引數型別,目前只能傳參來解決,比如printf和scanf通過%來判斷個數,通過%s,%d,%f等中s,d,f來區分型別。
C語言(變參函式)
c語言雖然沒有c 的函式過載特性,但也可以實現變參,但要保證第乙個引數資訊的完整性。拓展 定義變參函式時,第乙個引數一般是字串,攜帶後續變參的型別和數量資訊,變參使用三點來表示,如 void sumup const char info,再使用va list va start va arg 和va e...
SpringBoot中的異常處理方式
springboot中有五種處理異常的方式 springboot預設的處理異常機制 springboot預設的已經提供了一套處理異常的機制。一旦程式出現了異常springboot就像 error的url傳送請求。在springboot中提供了乙個叫basicexceptioncontroller來處...
矩陣中範數的處理方式
如果是向量範數,則p範數則表示為 比絕對值多了兩條豎線 x p sqrt p tag 公式 1 中 x x 1,x 2,x n 如果 p 2 實際上就是最常見的歐氏距離 歐幾里德範數 如果 p 0 稱為0範數,結果等於1。初中學過,在乙個平面直角座標系中,計算 x1 和 x2 兩點之間的距離,用下面...