青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

C語言變參函數解析

1 函數聲明
   首先,要實現類似printf()的變參函數,函數的最后一個參數要用 ... 表示,如
     int log(char * arg1, ...)
這樣編譯器才能知道這個函數是變參函數。這個參數與變參函數的內部實現完全沒有關系,只是讓編譯器在編譯調用此類函數的語句時不計較參數多少老老實實地把全部參數壓棧而不報錯,當然...之前至少要有一個普通的參數,這是由實現手段限制的。


2 函數實現
   C語言通過幾個宏實現變參的尋址。下面是linux2.18內核源碼里這幾個宏的定義,相信符合C89,C99標準的C語言基本都是這樣定義的。
   typedef char *va_list;
/*
   Storage alignment properties -- 堆棧按機器字對齊
*/
#define _AUPBND            (sizeof (acpi_native_uint) - 1)
#define _ADNBND            (sizeof (acpi_native_uint) - 1)
/*
   Variable argument list macro definitions -- 變參函數內部實現需要用到的宏
*/
#define _bnd(X, bnd)          (((sizeof (X)) + (bnd)) & (~(bnd)))
#define va_arg(ap, T)        (*(T *)(((ap) += (_bnd (T, _AUPBND))) - (_bnd (T,_ADNBND))))
#define va_end(ap)          (void) 0
#define va_start(ap, A)        (void) ((ap) = (((char *) &(A)) + (_bnd (A,_AUPBND))))
   下面以x86 32位機為例分析這幾個宏的用途
   要理解這幾個宏需要對C語言如何傳遞參數有一定了解。與PASCAL相反,與stdcall 相同,C語言傳遞參數時是用push指令從右到左將參數逐個壓棧,因此C語言里通過棧指針來訪問參數。雖然X86的push一次可以壓2,4或8個字節入棧,C語言在壓參數入棧時仍然是機器字的size為最小單位的,也就是說參數的地址都是字對齊的,這就是_bnd(X,bnd)存在的原因。另外補充一點常識,不管是匯編還是C,編譯出的X86函數一般在進入函數體后立即執行
   push ebp
   mov ebp, esp
   這兩條指令。首先把ebp入棧,然后將當前棧指針賦給ebp,以后訪問棧里的參數都使用ebp作為基指針。
   一一解釋這幾個宏的作用。
   _bnd(X,bnd) ,計算類型為X的參數在棧中占據的字節數,當然是字對齊后的字節數了。acpi_native_unit是一個機器字,32位機的定義是:typedef u32 acpi_native_uint;
   顯然,_AUPBND ,_ADNBND 的值是 4-1 == 3 == 0x00000003 ,按位取反( ~(bnd))就是0xfffffffc 。
因此,_bnd(X,bnd) 宏在32位機下就是
   ( (sizeof(X) + 3)&0xfffffffc )
很明顯,其作用是--倘若sizeof(X)不是4的整數倍,去余加4。
   _bnd(sizeof(char),3) == 4
   _bnd(sizeof(struct size7struct),3) == 8
   va_start(ap,A) ,初始化參數指針ap,將函數參數A右邊第一個參數的地址賦給ap。 A必須是一個參數的指針,所以此種類型函數至少要有一個普通的參數啊。像下面的例子函數,就是將第二個參數的指針賦給ap。
   va_arg(ap,T) ,獲得ap指向參數的值,并使ap指向下一個參數,T用來指明當前參數類型。
   注意((ap) += (_bnd (T, _AUPBND))) 是被一對括號括起來的,然后才減去(_bnd (T, _ADNBND),
而_AUPBND和_ADNBND是相等的。所以取得的值是ap當前指向的參數值,但是先給ap加了當前參數在字對齊后所占的字節數,使其指向了下一個參數。
va_end(ap), 作用是美觀。


3 總結
先用一個 ... 參數聲明函數是變參函數,接下來在函數內部以va_start(ap,A)宏初始化參數指針,然后就可以用va_arg(ap,類型)從左到右逐個獲取參數值了
分析到此處算是一清二白了,下面給一個例子
int log(char * fmt,...)
{
va_list ap;
int d;
char c, *p, *s;
va_start(ap, fmt);
while (*fmt)
   switch(*fmt++) {
   case 's':        /* string */
   s = va_arg(ap, char *);
   printf("string %s\n", s);
   break;
   case 'd':        /* int */
   d = va_arg(ap, int);
   printf("int %d\n", d);
   break;
   case 'c':        /* char */
   c = va_arg(ap, char);
   printf("char %c\n", c);
   break;
}
va_end(ap);
}

posted on 2008-06-11 14:11 肥仔 閱讀(271) 評論(0)  編輯 收藏 引用 所屬分類: C++ 基礎

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产自产2019最新不卡| 欧美连裤袜在线视频| 久久精品视频在线| 欧美阿v一级看视频| 亚洲国产精品福利| 亚洲精品乱码久久久久久蜜桃91| 亚洲午夜精品国产| 久久国产一区二区| 亚洲福利国产| 欧美日韩亚洲综合在线| 亚洲一区三区在线观看| 免费日韩av| 中文一区字幕| 黑人一区二区三区四区五区| 一本到12不卡视频在线dvd| 亚洲高清一二三区| 欧美另类专区| 欧美一区视频| 亚洲一线二线三线久久久| 国产欧美在线视频| 免费成人激情视频| 亚洲无毛电影| 欧美国产日韩在线观看| 亚洲欧美中日韩| 亚洲国内自拍| 国产精品一区视频| 欧美国产一区二区在线观看| 老**午夜毛片一区二区三区| 一本大道久久a久久综合婷婷| 欧美刺激性大交免费视频| 亚洲一区观看| 亚洲电影在线观看| 久久精品国产精品亚洲| 国产亚洲欧美一区| 欧美日韩国内| 乱人伦精品视频在线观看| 亚洲综合好骚| 亚洲精品小视频在线观看| 亚洲精品欧美日韩| 欧美日本高清一区| 久久在线91| 亚洲欧美一区在线| 在线视频亚洲| 亚洲精品久久| 麻豆精品视频在线| 久久成年人视频| 黄色日韩网站视频| 国产精品一区二区在线观看网站| 欧美一区二区三区精品| 99日韩精品| 亚洲欧美日韩第一区| 日韩视频在线观看| 最新日韩在线视频| 亚洲国产成人av| 欧美日韩国产免费观看| 久久综合婷婷| 久久精品一级爱片| 久久激情网站| 日韩午夜在线观看视频| 欧美激情一区二区三区在线视频| 日韩午夜在线电影| 亚洲精品影视在线观看| 亚洲国内精品在线| 亚洲电影第三页| 亚洲第一在线综合在线| 一区二区在线视频观看| 国内精品视频久久| 黄色成人在线网站| 欧美精品日韩一本| 欧美精品97| 亚洲第一福利在线观看| 国产农村妇女精品| 欧美黄免费看| 欧美国产视频日韩| 亚洲激情专区| 亚洲茄子视频| 一本色道婷婷久久欧美| av不卡在线| 亚洲综合日韩| 欧美伊人久久久久久久久影院| 最新高清无码专区| 久久精品成人| 久久综合狠狠综合久久综青草| 制服诱惑一区二区| 亚洲伊人网站| 久久国产精品久久精品国产 | 欧美日韩亚洲一区| 欧美日韩国产小视频| 国产精品ⅴa在线观看h| 国产精品区一区二区三区| 国产日韩欧美a| 在线不卡亚洲| 一区二区不卡在线视频 午夜欧美不卡' | 9国产精品视频| 欧美日韩激情小视频| 亚洲一区二区在线免费观看| 91久久久久久国产精品| 国产精品亚洲人在线观看| 国产日韩欧美一区二区| 精品成人国产| 99精品视频一区二区三区| 亚洲欧美在线看| 美女脱光内衣内裤视频久久网站| 欧美亚洲网站| 99国产精品99久久久久久粉嫩| 韩国精品在线观看| 亚洲精品免费观看| 亚洲欧美日韩国产综合精品二区 | 亚洲一区二区三区在线视频| 亚洲精品视频啊美女在线直播| 极品av少妇一区二区| 国产日本亚洲高清| 亚洲精品视频啊美女在线直播| 国产精品高清免费在线观看| 国产一区二区黄色| 久久久久国产一区二区三区| 欧美电影在线播放| 国产日韩欧美精品一区| 99国产精品久久久| 亚洲免费观看视频| 久久久在线视频| 久久亚洲风情| 日韩视频在线一区| 在线亚洲免费视频| 美女啪啪无遮挡免费久久网站| 老司机免费视频一区二区| 久久精品72免费观看| 欧美亚洲第一页| 亚洲日本va午夜在线电影 | 国产精品亚洲综合久久| 亚洲成人在线免费| 午夜一区二区三区在线观看| 午夜久久久久久久久久一区二区| 亚洲欧美www| 亚洲国语精品自产拍在线观看| 亚洲国产高清一区| 欧美一区在线直播| 国产精品久久91| 99视频热这里只有精品免费| 玖玖在线精品| 国产一区二区三区免费不卡| 国产欧美亚洲日本| 日韩亚洲不卡在线| 欧美风情在线观看| 久久精品系列| 国产亚洲一区二区精品| 国产三区精品| 亚洲欧美国产视频| 久久久欧美精品sm网站| 一本一本久久| 欧美日韩精品是欧美日韩精品| 国产精品成人一区二区| 国产一区视频在线看| 欧美亚洲在线观看| 亚洲一级在线| 欧美午夜www高清视频| 中文精品视频| 久久免费少妇高潮久久精品99| 欧美xx视频| 久久精品国产成人| 好看的日韩视频| 一区二区三区蜜桃网| 亚洲七七久久综合桃花剧情介绍| 亚洲小少妇裸体bbw| 国产精品久久九九| 欧美在线观看视频一区二区三区| 男人天堂欧美日韩| 久久躁日日躁aaaaxxxx| 在线免费日韩片| 午夜精品久久久久久久99黑人| 六月天综合网| 欧美3dxxxxhd| 一区二区三区www| 蜜桃伊人久久| 欧美99久久| 亚洲图片在线观看| 亚洲视频一区| 国产在线精品一区二区夜色| 美国成人毛片| 欧美精品免费看| 欧美一区1区三区3区公司| 午夜天堂精品久久久久| 尤物精品国产第一福利三区| 亚洲电影免费在线观看| 欧美天天视频| 久久婷婷人人澡人人喊人人爽| 99精品欧美| 国产午夜精品理论片a级大结局| 一区二区久久久久久| 亚洲一区二区精品视频| 红桃视频亚洲| 亚洲精品社区| 免费h精品视频在线播放| 在线视频你懂得一区二区三区| 久久一二三四| 欧美日韩一区二区三区在线| 亚洲国产影院| 久久久久久日产精品| 欧美激情综合亚洲一二区| 欧美一区影院|