在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > C/C++可變參數(shù)函數(shù)

            C/C++可變參數(shù)函數(shù)

            ——
            作者: 時間:2007-05-10 來源: 收藏

            c/c++支持,即的參數(shù)是不確定的。

            一、為什么要使用?

            一般我們編程的時候,函數(shù)中形式參數(shù)的數(shù)目通常是確定的,在調(diào)用時要依次給出與形式參數(shù)對應(yīng)的所有實際參數(shù)。但在某些情況下希望函數(shù)的參數(shù)個數(shù)可以根據(jù)需要確定,因此c語言引入函數(shù)。這也是c功能強大的一個方面,其它某些語言,比如fortran就沒有這個功能。

            典型的可變參數(shù)函數(shù)的例子有大家熟悉的printf()、scanf()等。

            二、c/c++如何實現(xiàn)可變參數(shù)的函數(shù)?

            為了支持可變參數(shù)函數(shù),語言引入新的調(diào)用協(xié)議, 即語言調(diào)用約定 __cdecl 。 采用/語言編程的時候,默認使用這個調(diào)用約定。如果要采用其它調(diào)用約定,必須添加其它關(guān)鍵字聲明,例如WIN32 API使用PASCAL調(diào)用約定,函數(shù)名字之前必須加__stdcall關(guān)鍵字。

            采用C調(diào)用約定時,函數(shù)的參數(shù)是從右到左入棧,個數(shù)可變。由于函數(shù)體不能預(yù)先知道傳進來的參數(shù)個數(shù),因此采用本約定時必須由函數(shù)調(diào)用者負責堆棧清理。舉個例子:

            //C調(diào)用約定函數(shù)
            int __cdecl Add(int a, int b)
            {
            return (a + b);
            }

            函數(shù)調(diào)用:
            Add(1, 2);
            //匯編代碼是:
            push 2 ;參數(shù)b入棧
            push 1 ;參數(shù)a入棧
            call @Add ;調(diào)用函數(shù)。其實還有編譯器用于定位函數(shù)的表達式這里把它省略了
            add esp,8 ;調(diào)用者負責清棧

            如果調(diào)用函數(shù)的時候使用的調(diào)用協(xié)議和函數(shù)原型中聲明的不一致,就會導(dǎo)致棧錯誤,這是另外一個話題,這里不再細說。

            另外c/c++編譯器采用宏的形式支持可變參數(shù)函數(shù)。這些宏包括va_start、va_arg和va_end等。之所以這么做,是為了增加程序的可移植性。屏蔽不同的硬件平臺造成的差異。

            支持可變參數(shù)函數(shù)的所有宏都定義在stdarg.h 和 varargs.h中。例如標準ANSI形式下,這些宏的定義是:

            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是為了按照整數(shù)字節(jié)對齊指針,因為c調(diào)用協(xié)議下面,參數(shù)入棧都是整數(shù)字節(jié)(指針或者值)。

            三、如何定義這類的函數(shù)。

            可變參數(shù)函數(shù)在不同的系統(tǒng)下,采用不同的形式定義。

            1、用ANSI標準形式時,參數(shù)個數(shù)可變的函數(shù)的原型聲明是:

            type funcname(type para1, type para2, …);

            關(guān)于這個定義,有三點需要說明:

            一般來說,這種形式至少需要一個普通的形式參數(shù),可變參數(shù)就是通過三個’.'來定義的。所以”…”不表示省略,而是函數(shù)原型的一部分。type是函數(shù)返回值和形式參數(shù)的類型。
            例如:

            int MyPrintf(char const* fmt, …);

            但是,我們也可以這樣定義函數(shù):

            void MyFunc(…);

            但是,這樣的話,我們就無法使用函數(shù)的參數(shù)了,因為無法通過上面所講的宏來提取每個參數(shù)。所以除非你的函數(shù)代碼中的確沒有用到參數(shù)表中的任何參數(shù),否則必須在參數(shù)表中使用至少一個普通參數(shù)。

            注意,可變參數(shù)只能位于函數(shù)參數(shù)表的最后。不能這樣:

            void MyFunc(…, int i);

            2、采用與UNIX 兼容系統(tǒng)下的聲明方式時,參數(shù)個數(shù)可變的函數(shù)原型是:

            type funcname(va_alist);

            但是要求函數(shù)實現(xiàn)的時候,函數(shù)名字后面必須加上va_dcl。例如:

            #include
            int average( va_list );

            void main( void )
            {
            。。。//代碼
            }

            /* UNIX兼容形式*/
            int average( va_alist )
            va_dcl
            {
            。。。//代碼
            }

            這種形式不需要提供任何普通的形式參數(shù)。type是函數(shù)返回值的類型。va_dcl是對函數(shù)原型聲明中參數(shù)va_alist的詳細聲明,實際是一個宏定義。根據(jù)平臺的不同,va_dcl的定義稍有不同。

            在varargs.h中,va_dcl的定義后面已經(jīng)包括了一個分號。因此函數(shù)實現(xiàn)的時候,va_dcl后不再需要加上分號了。

            3、采用頭文件stdarg.h編寫的程序是符合ANSI標準的,可以在各種操作系統(tǒng)和硬件上運行;而采用頭文件varargs.h的方式僅僅是為了與以前的程序兼容,兩種方式的基本原理是一致的,只是在語法形式上有一些細微的區(qū)別。 所以一般編程的時候使用stdarg.h。下面的所有例子代碼都采用ANSI標準格式。

            四、可變參數(shù)函數(shù)的基本使用方法

            下面通過若干例子,說明如何實現(xiàn)可變參數(shù)函數(shù)的定義和調(diào)用。

            //================================ 例子程序1 ===============
            #include < stdio.h >
            #include < string.h >
            #include < stdarg.h >

            /* 函數(shù)原型聲明,至少需要一個確定的參數(shù),注意括號內(nèi)的省略號 */
            int demo( char *, … );

            void main( void )
            {
            demo(”DEMO”, “This”, “is”, “a”, “demo!”, “