<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    關于C的變長參數的思考心得

    某些情況下希望函數的參數個數可以根據需要確定。典型的例子有大家熟悉的函數printf()、scanf()和系統調用execl()等。那么它們是怎樣實現的呢?C編譯器通常提供了一系列處理這種情況的宏,以屏蔽不同的硬件平臺造成的差異,增加程序的可移植性。這些宏包括va_start、va_arg和va_end等。


    ---- 采用ANSI標準形式時,參數個數可變的函數的原型聲明是:

    type funcname(type para1, type para2, ...)
    ---- 這種形式至少需要一個普通的形式參數,后面的省略號不表示省略,而是函數原型的一部分。type是函數返回值和形式參數的類型。
    ---- 采用與UNIX System V兼容的聲明方式時,參數個數可變的函數原型是:

    type funcname(va_alist)
    va_dcl

    ---- 這種形式不需要提供任何普通的形式參數。type是函數返回值的類型。va_dcl是對函數原型聲明中參數va_alist的詳細聲明,實際是一個宏定義,對不同的硬件平臺采用不同的類型來定義,但在最后都包括了一個分號。因此va_dcl后不再需要加上分號了。va_dcl在代碼中必須原樣給出。va_alist在VC中可以原樣給出,也可以略去。
    ---- 此外,采用頭文件stdarg.h編寫的程序是符合ANSI標準的,可以在各種操作系統和硬件上運行;而采用頭文件varargs.h的方式僅僅是為了與以前的程序兼容。所以建議大家使用前者。以下主要就前一種方式對參數的處理做出說明。兩種方式的基本原理是一致的,只是在語法形式上有一些細微的區別。

    ---- va_start使argp指向第一個可選參數。va_arg返回參數列表中的當前參數并使argp指向參數列表中的下一個參數。va_end把argp指針清為NULL。函數體內可以多次遍歷這些參數,但是都必須以va_start開始,并以va_end結尾。

    ---- 調用者在實際調用參數個數可變的函數時,要通過一定的方法指明實際參數的個數,例如把最后一個參數置為空字符串(系統調用execl()就是這樣的)、-1或其他的方式(函數printf()就是通過第一個參數,即輸出格式的定義來確定實際參數的個數的)。

    ---- 下面給出一個具體的例子。是采用了符合ANSI標準的形式的代碼。代碼中加了一些注釋,這里就不再解釋了。該例子已經在VC/Windows XP、CC/AIX4.3.2.0、GCC/SUSE7.3環境下編譯并正常運行。

    ---- 1、演示如何使用參數個數可變的函數,采用ANSI標準形式

    #include < stdio.h >
    #include < string.h >
    #include < stdarg.h >

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

    void main( void )
    {
    demo("DEMO", "This", "is", "a", "demo!", "\0");
    }

    /* ANSI標準形式的聲明方式,括號內的省略號表示可選參數 */
    int demo( char *msg, ... )
    {
    va_list argp; /* 定義保存函數參數的結構 */
    int argno = 0; /* 紀錄參數個數 */
    char *para; /* 存放取出的字符串參數 */

    /* argp指向傳入的第一個可選參數,
    msg是最后一個確定的參數 */
    va_start( argp, msg );

    while (1) {
    para = va_arg( argp, char *); /*
    取出當前的參數,類型為char *. */
    if ( strcmp( para, "\0") == 0 )
    /* 采用空串指示參數輸入結束 */
    break;
    printf("Parameter #%d is: %s\n", argno, para);
    argno++;
    }
    va_end( argp ); /* 將argp置為NULL */
    return 0;
    }
    轉自:http://www.yourblog.org/Data/20041/2521.html

    posted on 2005-07-10 17:00 weidagang2046 閱讀(188) 評論(0)  編輯  收藏 所屬分類: C/C++

    主站蜘蛛池模板: 亚洲AV无码久久久久网站蜜桃| 国产亚洲无线码一区二区| 亚洲人成网站999久久久综合| 亚洲视频免费在线看| 亚洲av色影在线| 久久久久久久99精品免费| 亚洲卡一卡2卡三卡4卡无卡三 | 久久亚洲精品无码播放| 人体大胆做受免费视频| 亚洲午夜成人精品电影在线观看| 一出一进一爽一粗一大视频免费的| 五月婷婷亚洲综合| 亚洲成AV人在线观看天堂无码| 全黄大全大色全免费大片| 亚洲AV无码精品色午夜在线观看| 日韩精品免费在线视频| 久久亚洲美女精品国产精品| 99爱在线精品免费观看| 亚洲欧美日韩久久精品| 亚洲乱码中文字幕手机在线| 国产婷婷成人久久Av免费高清| 亚洲日本在线观看| 最近中文字幕免费mv视频8| 国产成人+综合亚洲+天堂| 中文字幕日韩亚洲| 最近2022中文字幕免费视频 | 一本色道久久88亚洲综合| 中文字幕乱码免费看电影| 亚洲国产视频网站| 国产成人精品免费视频大全五级 | 永久免费精品影视网站| 亚洲精品成人片在线观看精品字幕| 97在线视频免费| 亚洲av日韩av永久在线观看 | 久久久久久久99精品免费 | ssswww日本免费网站片| 亚洲视频免费播放| 亚洲国产精品成人网址天堂| 99久久综合精品免费| 精品在线观看免费| 久久久久亚洲精品天堂|