• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 用C語言實現參數個數可變的函數

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    張文亮 采用C語言編程的時候,函數中形式參數的數目通常是確定的,在調用時要依次給出與形式參數對應的所有實際參數。但在某些情況下希望函數的參數個數可以根據需要確定。典型的例子有大家熟悉的函數printf()、scanf()和系統調用execl()等。那么它們是怎樣實
    張文亮

      采用C語言編程的時候,函數中形式參數的數目通常是確定的,在調用時要依次給出與形式參數對應的所有實際參數。但在某些情況下希望函數的參數個數可以根據需要確定。典型的例子有大家熟悉的函數printf()、scanf()和系統調用execl()等。那么它們是怎樣實現的呢?

      C編譯器通常提供了一系列處理這種情況的宏,以屏蔽不同的硬件平臺造成的差異,增加程序的可移植性。這些宏包括va—start、va—arg和va—end等。

      使用這些宏有兩種不同的形式,二者在程序中包括的頭文件不同,宏的定義也存在一些差別。這兩種方式對應的頭文件和宏的聲明見表1。

      采用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中可以原樣給出,也可以略去,但在UNIX上的CC或Linux上的GCC中都要省略掉。此外,采用頭文件stdarg.h編寫的程序是符合ANSI標準的,可以在各種操作系統和硬件上運行,而采用頭文件varargs.h的方式僅僅是為了與以前的程序兼容。所以建議大家使用前者。兩種方式的基本原理是一致的,只是在語法形式上有一些細微的區別。以下主要就前一種方式對參數的處理做出說明。

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

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

      下面給出一個具體的例子,前一部分是采用了符合ANSI標準形式的代碼,后一部分是采用了與UNIX System V兼容方式的代碼。代碼中加了一些注釋,這里就不再解釋了。該例子已經在VC/Windows NT4.0、CC/AIX4.3.2.0、GCC/Redhat Linux 6.0環境下編譯并正常運行。

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

     ?。nclude 〈stdio.h〉

     ?。nclude 〈string.h〉

     ?。nclude 〈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;

      }

      2.演示如何使用參數個數可變的函數,采用與UNIX System V兼容的方式

     ?。nclude 〈stdio.h〉

     ?。nclude 〈string.h〉

     ?。nclude 〈varargs.h〉

      /? 函數原型聲明,括號內的類型va—list在VC/Windows NT4.0可以保留,但在AIX和Linux下需要去掉,即改成int demo( ) ?/

      int demo( va—list );

      void main( void )

      {

       demo(″This″, ″is″, ″a″, ″demo!″, ″\0″);

      }

      /? UNIX System V采用的聲明方式,括號內是va—alist,不是va—list,而且va—dcl后面不需要分號 ?/

      int demo( va—alist )

      va—dcl

      {

      va—list argp;

       /? 定義保存函數參數的結構 ?/

       int argno = 0; /? 紀錄參數個數 ?/

       char ?para;

      /? 存放取出的字符串參數 ?/

      va—start( argp );

      /? argp指向第一個可選參數 ?/

      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;

      }

      表1   ansi標準形式 unix systemⅤ兼容方式 頭文件 #include 〈stdarg.h〉 #include 〈varargs.h〉 va_start void va_start(argp, paran) va_list argp; void va_start(argp) va_list argp; va_arg type va_arg(argp, type) va_list argp; type va_arg(argp, type) va_list argp; va_end void va_end(argp) va_list argp; void va_end(argp) va_list argp;

     

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>