• <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>

            醬壇子

            專(zhuān)注C++技術(shù) 在這里寫(xiě)下自己的學(xué)習(xí)心得 感悟 和大家討論 共同進(jìn)步(歡迎批評(píng)!!!)

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              66 Posts :: 16 Stories :: 236 Comments :: 0 Trackbacks

            公告

            王一偉 湖南商學(xué)院畢業(yè) 電子信息工程專(zhuān)業(yè)

            常用鏈接

            留言簿(19)

            我參與的團(tuán)隊(duì)

            搜索

            •  

            積分與排名

            • 積分 - 387835
            • 排名 - 64

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            可變參數(shù)函數(shù)設(shè)計(jì)
            #include "stdafx.h"
            #include 
            <stdio.h>
            #include 
            <stdarg.h>

            int mul(int num,int data1,)
            {
                
            int total = data1;
                
            int arg,i;
                va_list ap;
                va_start(ap,data1);
                
            for(i=1;i<num;i++)
                {
                    arg 
            = va_arg(ap,int);
                    total
            *=arg;
                }
                va_end(ap);
                
            return total;
            }

            long mul2(int i,)
            {
                
            int *p,j;
                p 
            = &i+1;//p指向參數(shù)列表下一個(gè)位置
                long s = *p;
                
            for (j=1;j<i;j++)
                    s 
            *= p[j];
                
            return s;
            }

            int main()
            {
                printf(
            "%d\n",mul(3,2,3,5));
                printf(
            "%d\n",mul2(3,2,3,5));
                
            return 0;
            }



            printf的設(shè)計(jì)
            #include "stdio.h"
            #include 
            "stdlib.h"
            #include 
            <stdarg.h>

            void myprintf(char* fmt, )        //一個(gè)簡(jiǎn)單的類(lèi)似于printf的實(shí)現(xiàn),//參數(shù)必須都是int 類(lèi)型
            {
                
            //char* pArg=NULL;               //等價(jià)于原來(lái)的va_list
                va_list pArg;
                
            char c;
               
               
            // pArg = (char*) &fmt;          //注意不要寫(xiě)成p = fmt !!因?yàn)檫@里要對(duì)參數(shù)取址,而不是取值
              
            // pArg += sizeof(fmt);         //等價(jià)于原來(lái)的va_start         
                va_start(pArg,fmt);

                
            do
                {
                    c 
            =*fmt;
                    
            if (c != '%')
                    {
                        putchar(c);            
            //照原樣輸出字符
                    }
                    
            else
                    {
            //按格式字符輸出數(shù)據(jù)
                        switch(*++fmt)
                        {
                        
            case 'd':
                            printf(
            "%d",*((int*)pArg));           
                            
            break;
                        
            case 'x':
                            printf(
            "%#x",*((int*)pArg));
                            
            break;
                        
            case 'f':
                            printf(
            "%f",*((float*)pArg));
                        
            default:
                            
            break;
                        }
                        
            //pArg += sizeof(int);               //等價(jià)于原來(lái)的va_arg
                        va_arg(pArg,int);
                    }
                    
            ++fmt;
                }
            while (*fmt != '\0');
                
            //pArg = NULL;                               //等價(jià)于va_end
                va_end(pArg);
                
            return;
            }
            int main(int argc, char* argv[])
            {
                
            int i = 1234;
                
            int j = 5678;
               
                myprintf(
            "the first test:i=%d",i,j);
                myprintf(
            "the secend test:i=%f; %x;j=%d;",i,0xabcd,j);
                system(
            "pause");
                
            return 0;
            }


            可變參數(shù)在編譯器中的處理 

                我們知道va_start,va_arg,va_end是在stdarg.h中被定義成宏的, 由于1)硬件平臺(tái)的不同 2)編譯器的不同,所以定義的宏也有所不同,下面以VC++stdarg.hx86平臺(tái)的宏定義摘錄如下(’"’號(hào)表示折行):
            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)主要是為了某些需要內(nèi)存的對(duì)齊的系統(tǒng).C語(yǔ)言的函數(shù)是從右向左壓入堆棧的,(1)是函數(shù)的參數(shù)在堆棧中的分布位置.我們看到va_list被定義成char*,有一些平臺(tái)或操作系統(tǒng)定義為void*.再看va_start的定義,定義為&v+_INTSIZEOF(v),&v是固定參數(shù)在堆棧的地址,所以我們運(yùn)行va_start(ap, v)以后,ap指向第一個(gè)可變參數(shù)在堆棧的地址,如圖:

            高地址|-----------------------------| 
            |函數(shù)返回地址 | 
            |-----------------------------| 
            || 
            |-----------------------------| 
            |第n個(gè)參數(shù)(第一個(gè)可變參數(shù)) | 
            |-----------------------------|<--va_start后ap指向 
            |第n-1個(gè)參數(shù)(最后一個(gè)固定參數(shù))| 
            低地址
            |-----------------------------|<-- &
            圖( 
            1 ) 

                然后,我們用va_arg()取得類(lèi)型t的可變參數(shù)值,以上例為int型為例,我們看一下va_argint型的返回值: j= ( *(int*)((ap += _INTSIZEOF(int))-_INTSIZEOF(int)) );
            首先ap+=sizeof(int),已經(jīng)指向下一個(gè)參數(shù)的地址了.然后返回ap-sizeof(int)int*指針,這正是第一個(gè)可變參數(shù)在堆棧里的地址(2).然后用*取得這個(gè)地址的內(nèi)容(參數(shù)值)賦給j.

            高地址|-----------------------------| 
            |函數(shù)返回地址 | 
            |-----------------------------| 
            || 
            |-----------------------------|<--va_arg后ap指向 
            |第n個(gè)參數(shù)(第一個(gè)可變參數(shù)) | 
            |-----------------------------|<--va_start后ap指向 
            |第n-1個(gè)參數(shù)(最后一個(gè)固定參數(shù))| 
            低地址
            |-----------------------------|<-- &
            圖( 
            2 ) 

                最后要說(shuō)的是va_end宏的意思,x86平臺(tái)定義為ap=(char*)0;使ap不再指向堆棧,而是跟NULL一樣.有些直接定義為((void*)0),這樣編譯器不會(huì)為va_end產(chǎn)生代碼,例如gcclinuxx86平臺(tái)就是這樣定義的.在這里大家要注意一個(gè)問(wèn)題:由于參數(shù)的地址用于va_start,所以參數(shù)不能聲明為寄存器變量或作為函數(shù)或數(shù)組類(lèi)型.關(guān)于va_start, va_arg, va_end的描述就是這些了,我們要注意的是不同的操作系統(tǒng)和硬件平臺(tái)的定義有些不同,但原理卻是相似的

            posted on 2007-09-02 12:29 @王一偉 閱讀(1315) 評(píng)論(0)  編輯 收藏 引用

            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            色婷婷综合久久久久中文| 日日狠狠久久偷偷色综合0| 亚洲AV无码久久寂寞少妇| 久久久久久久亚洲Av无码| 亚洲国产成人久久综合碰碰动漫3d| 成人精品一区二区久久久| 久久频这里精品99香蕉久| 久久久久无码精品国产不卡| 久久国产免费直播| 久久精品一本到99热免费| 久久99热这里只频精品6| 久久国产一区二区| 国产成人无码精品久久久性色| 久久中文娱乐网| 人妻丰满AV无码久久不卡| 久久婷婷人人澡人人| www.久久热.com| 亚洲精品午夜国产VA久久成人| 久久成人18免费网站| 久久这里只有精品首页| 久久精品中文字幕无码绿巨人| 人人狠狠综合久久亚洲| 精品99久久aaa一级毛片| 精品久久一区二区| 久久久久AV综合网成人| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 91久久九九无码成人网站| A级毛片无码久久精品免费 | 久久精品国产精品青草| 欧美黑人又粗又大久久久| 波多野结衣AV无码久久一区| 亚洲国产精品成人久久蜜臀| 久久精品成人免费观看97| 精品久久久久中文字| 久久综合九色综合久99| 久久精品国产99久久无毒不卡 | 久久综合久久综合久久综合| 99久久人妻无码精品系列蜜桃| 国产精品久久久久久影院| 91精品国产乱码久久久久久| 久久久久成人精品无码中文字幕|