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

woaidongmao

文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見(jiàn)諒!~
隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
數(shù)據(jù)加載中……

C語(yǔ)言變參函數(shù)解析

1 函數(shù)聲明
   首先,要實(shí)現(xiàn)類似printf()的變參函數(shù),函數(shù)的最后一個(gè)參數(shù)要用 ... 表示,如
     int log(char * arg1, ...)
這樣編譯器才能知道這個(gè)函數(shù)是變參函數(shù)。這個(gè)參數(shù)與變參函數(shù)的內(nèi)部實(shí)現(xiàn)完全沒(méi)有關(guān)系,只是讓編譯器在編譯調(diào)用此類函數(shù)的語(yǔ)句時(shí)不計(jì)較參數(shù)多少老老實(shí)實(shí)地把全部參數(shù)壓棧而不報(bào)錯(cuò),當(dāng)然...之前至少要有一個(gè)普通的參數(shù),這是由實(shí)現(xiàn)手段限制的。


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


3 總結(jié)
先用一個(gè) ... 參數(shù)聲明函數(shù)是變參函數(shù),接下來(lái)在函數(shù)內(nèi)部以va_start(ap,A)宏初始化參數(shù)指針,然后就可以用va_arg(ap,類型)從左到右逐個(gè)獲取參數(shù)值了
分析到此處算是一清二白了,下面給一個(gè)例子
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 肥仔 閱讀(270) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C++ 基礎(chǔ)

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一本色道久久88精品综合| 免费观看一级特黄欧美大片| 国产精品亚洲激情| 欧美性做爰猛烈叫床潮| 欧美日韩精品一区二区三区四区| 老司机久久99久久精品播放免费 | 欧美一区二区三区电影在线观看| 亚洲天堂成人| 午夜精品在线| 久久久之久亚州精品露出| 亚洲成人在线视频网站| 亚洲三级毛片| 亚洲免费中文| 欧美激情一二三区| 国产亚洲制服色| 亚洲经典在线| 亚洲欧美精品在线| 久久性天堂网| 一区二区日韩精品| 午夜欧美精品| 久久尤物电影视频在线观看| 欧美日韩视频免费播放| 国产精品毛片在线看| 国产字幕视频一区二区| 在线视频精品一区| 久久久精彩视频| 一本综合精品| 久久网站免费| 国产日产欧美a一级在线| 亚洲国产成人久久| 久久精品观看| aa级大片欧美三级| 久久综合网络一区二区| 国产欧美一区二区三区国产幕精品| 激情欧美一区二区| 午夜在线a亚洲v天堂网2018| 亚洲全部视频| 美女网站久久| 樱桃视频在线观看一区| 午夜久久久久久| 亚洲精品在线视频观看| 亚洲在线播放电影| 亚洲精品国产精品国自产在线| 午夜在线精品偷拍| 亚洲久久成人| 欧美国产日韩二区| 亚洲福利视频一区| 久久一区二区三区国产精品| 午夜国产精品影院在线观看 | 国产精品一二一区| 日韩亚洲欧美高清| 亚洲高清一区二| 美女露胸一区二区三区| 亚洲高清视频中文字幕| 美女视频黄a大片欧美| 欧美一级成年大片在线观看| 国产精品高清在线观看| 亚洲一卡久久| 正在播放亚洲| 国产噜噜噜噜噜久久久久久久久| 亚洲午夜在线视频| 日韩午夜中文字幕| 欧美日韩你懂的| 亚洲欧美日韩在线观看a三区| 一区二区三区欧美激情| 国产精品第三页| 欧美一区二区三区四区在线观看地址| 在线天堂一区av电影| 国产精品欧美经典| 久久精品一级爱片| 久久一区二区三区四区| 亚洲高清视频一区| 亚洲人成艺术| 国产麻豆日韩| 欧美成人午夜剧场免费观看| 欧美成人精品一区二区| 夜夜爽av福利精品导航| 中国女人久久久| 国产午夜精品久久久久久久| 欧美成人高清| 欧美色精品天天在线观看视频| 亚洲欧美另类中文字幕| 欧美一级在线播放| 日韩视频一区二区三区在线播放 | 一区二区三区 在线观看视频| 欧美性猛交xxxx乱大交退制版 | 国产欧美日韩视频| 麻豆成人在线播放| 欧美日韩国产成人在线| 欧美一区二区视频观看视频| 免费不卡欧美自拍视频| 亚洲午夜电影在线观看| 久久精品成人一区二区三区| 99精品热视频只有精品10| 亚洲综合色视频| 亚洲福利专区| 亚洲欧美在线x视频| 夜夜嗨av一区二区三区免费区| 久久久噜噜噜久久中文字免| 亚洲国产精品一区二区第四页av| 日韩一级黄色大片| 影音先锋久久久| 亚洲婷婷国产精品电影人久久| 国内精品久久久久影院优 | 免播放器亚洲| 国产精品日韩精品欧美在线| 欧美国产精品专区| 国产美女搞久久| 亚洲乱码精品一二三四区日韩在线| 国产一区二区三区最好精华液| 亚洲肉体裸体xxxx137| 国内偷自视频区视频综合| 夜夜精品视频| 亚洲人午夜精品| 久久九九99| 欧美一区二区在线免费播放| 欧美精品电影| 亚洲第一综合天堂另类专| 韩日欧美一区二区| 亚洲一区在线直播| 在线午夜精品自拍| 欧美激情第9页| 欧美激情精品久久久久久| 国产视频在线观看一区二区三区| av成人国产| 一区二区三区四区五区视频| 欧美福利影院| 亚洲第一页在线| 亚洲精品黄色| 欧美久久久久免费| 亚洲人成网站在线观看播放| 亚洲乱码国产乱码精品精天堂| 蘑菇福利视频一区播放| 欧美国产日韩在线| 亚洲激情视频在线播放| 男女精品网站| 亚洲国内精品| 一本色道久久综合精品竹菊| 欧美—级高清免费播放| 亚洲精品一二区| 亚洲一区亚洲| 国产日韩视频| 久久久精品一区| 亚洲电影专区| 国产精品99久久久久久人| 欧美性片在线观看| 亚洲——在线| 久久一区二区精品| 91久久极品少妇xxxxⅹ软件| 欧美国产精品| 亚洲视频精选| 久久久一区二区三区| 在线欧美福利| 欧美另类极品videosbest最新版本| 亚洲精品视频免费在线观看| 亚洲欧美日韩在线高清直播| 国模大胆一区二区三区| 蜜桃视频一区| 亚洲素人在线| 蜜桃精品久久久久久久免费影院| 亚洲精品在线二区| 国产精品夜夜夜一区二区三区尤| 欧美专区亚洲专区| 亚洲国产成人久久综合| 亚洲一区观看| 老鸭窝91久久精品色噜噜导演| 日韩午夜免费| 国产精品稀缺呦系列在线| 久久久久国产免费免费| 亚洲国产专区| 久久久久久久久岛国免费| 亚洲精品综合久久中文字幕| 国产伦精品一区二区三区四区免费| 久久久久国产精品一区三寸| 99re在线精品| 欧美承认网站| 久久精品91| 99精品国产在热久久| 国外成人在线视频| 欧美视频1区| 女人天堂亚洲aⅴ在线观看| 亚洲一区二区视频| 亚洲国产精品va在线看黑人动漫| 欧美怡红院视频| 夜久久久久久| 亚洲国产一区在线观看| 国产噜噜噜噜噜久久久久久久久| 欧美激情五月| 久久综合激情| 久久成人免费视频| 亚洲一区二区三区高清不卡| 欧美国产精品人人做人人爱| 久久综合狠狠综合久久激情| 性做久久久久久久免费看| 亚洲视频播放| 一本色道久久综合亚洲精品不卡| 在线看一区二区| 精品999在线观看| 国模大胆一区二区三区| 国产亚洲综合在线|