国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

編程入門:淺談C語言的可變參數

2019-11-17 05:37:21
字體:
來源:轉載
供稿:網友
  C語言中有些函數使用可變參數,比如常見的int PRintf( const char* format, ...),第一個參數format是固定的,其余的參數的個數和類型都不固定。  C語言用va_start等宏來處理這些可變參數。這些宏看起來很復雜,其實原理挺簡單,就是根據參數入棧的特點從最靠近第一個可變參數的固定參數開始,依次獲取每個可變參數的地址。下面我們來分析這些宏。  在stdarg.h頭文件中,針對不同平臺有不同的宏定義,我們選取X86平臺下的宏定義:

  typedef char *  va_list;  #define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )  #define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )  #define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )  #define va_end(ap)      ( ap = (va_list)0 )   _INTSIZEOF(n)宏是為了考慮那些內存地址需要對齊的系統,從宏的名字來應該是跟sizeof(int)對齊。一般的sizeof(int)=4,也就是參數在內存中的地址都為4的倍數。比如,假如sizeof(n)在1-4之間,那么_INTSIZEOF(n)=4;假如sizeof(n)在5-8之間,那么_INTSIZEOF(n)=8。  為了能從固定參數依次得到每個可變參數,va_start,va_arg充分利用下面兩點:  1. C語言在函數調用時,先將最后一個參數壓入棧  2. X86平臺下的內存分配順序是從高地址內存到低地址內存  高位地址  第N個可變參數  。。。  第二個可變參數  第一個可變參數      ? ap  固定參數           ? v  低位地址  由上圖可見,v是固定參數在內存中的地址,在調用va_start后,ap指向第一個可變參數。這個宏的作用就是在v的內存地址上增加v所占的內存大小,這樣就得到了第一個可變參數的地址。  接下來,可以這樣設想,假如我能確定這個可變參數的類型,那么我就知道了它占用了多少內存,依葫蘆畫瓢,我就能得到下一個可變參數的地址。  讓我再來看看va_arg,它先ap指向下一個可變參數,然后減去當前可變參數的大小即得到當前可變參數的內存地址,再做個類型轉換,返回它的值。  要確定每個可變參數的類型,有兩種做法,要么都是默認的類型,要么就在固定參數中包含足夠的信息讓程序可以確定每個可變參數的類型。比如,printf,程序通過分析format字符串就可以確定每個可變參數大類型。  最后一個宏就簡單了,va_end使得ap不再指向有效的內存地址。  看了這幾個宏,不禁讓我再次感慨,C語言太靈活了,而且代碼可以寫得非常簡潔,雖然有時候讓人看得不是很明白,但是一旦明白 過來,你肯定會為它擊掌叫好!  其實在varargs.h頭文件中定義了UNIX System V實行的va系列宏,而上面在stdarg.h頭文件中定義的是ANSI C形式的宏,這兩種宏是不兼容的,一般說來,我們應該使用ANSI C形式的va宏。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 苗栗市| 南靖县| 韩城市| 长武县| 淮阳县| 松潘县| 牙克石市| 沂源县| 永春县| 长宁县| 定日县| 邯郸市| 宁蒗| 阿克陶县| 全州县| 张家界市| 滁州市| 新乐市| 新邵县| 门源| 阿拉善左旗| 贡觉县| 洞口县| 应用必备| 淅川县| 武胜县| 青州市| 萝北县| 钟祥市| 道孚县| 鸡西市| 松潘县| 泰和县| 镇平县| 出国| 葫芦岛市| 和平区| 徐州市| 济阳县| 万安县| 探索|