乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C語言可變參數(shù)函數(shù)的使用及相關(guān)函數(shù)介紹

       CodeNutter 2016-06-16

                  By qianghaohao(Xqiang)

             在C語言中當(dāng)一個函數(shù)參數(shù)無法列舉出來,或者參數(shù)個數(shù)
       不確定,這時我們將函數(shù)聲明為可變參數(shù)的形式,根據(jù)需
       要傳適當(dāng)個數(shù)的參數(shù).舉例如下:
      int fun(char *fmt, ...);
      ... 表示此函數(shù)fmt后面可以傳任意數(shù)目的參數(shù).
      我們所熟悉的printf函數(shù)便是利用了這一特性,printf
      函數(shù)聲明如下:
      int printf(const char *, ...);
      以下介紹如何利用此類函數(shù)打印函數(shù)的所有參數(shù),總共
      介紹了三種方法:

      以此函數(shù)聲明為例:int fun(char *fmt, ...);
      在介紹之前得先搞清楚以下相關(guān)的函數(shù)(在stdarg.h中聲明):
      1.va_list
        定義一個va_list變量,后面的操作都和此變量有關(guān).
        ex: va_list ap;
      2.va_start
        初始化va_list變量,讓ap指向可變參數(shù)表的第一個參數(shù),即
        ...參數(shù)中的第一個參數(shù).此函數(shù)第一個參數(shù)為ap,第二個參
        數(shù)為第一個可變參數(shù)的前一個參數(shù),即...前的那一個參數(shù).
        ex: va_start(ap, fmt);
      3.va_arg
        獲取可變參數(shù),此函數(shù)第一個參數(shù)為ap,第二個參數(shù)為要獲取
        的類型.返回指定類型的的變量,然后讓ap指向可變參數(shù)表的
        下一個參數(shù).
        ex: va_arg(ap, char *);
      4.va_end
        使用完后釋放ap變量
        ex: va_end(ap);
      5. int vsprintf(char *string, char *format, va_list param);
         按照format格式化輸出參數(shù)到string,format類似于printf的
         格式化串,param是va_list變量.
         ex: ---摘自百度百科
          #include <stdarg.h>
          #include<stdio.h>
          char buffer[80];
          int vspf(char *fmt, ...)
          {
              va_list argptr;
              int cnt;
              va_start(argptr, fmt);
              cnt = vsprintf(buffer, fmt, argptr);
              va_end(argptr);
              return(cnt);
          }
          int main(void)
          {
              int inumber = 30;
              float fnumber = 90.0;
              char string[4] = "abc";
              vspf("%d %f %s", inumber, fnumber, string);
              printf("%s\n", buffer);
              return 0;
          }

       好了,現(xiàn)在有了前面的知識,現(xiàn)在正式開始介紹如何打印出可變參數(shù)函數(shù)的所有參數(shù):
       一.第一種方法(比較笨的一種方法,我不推薦這么做,除非有特殊需求吧):
            通過va_arg函數(shù)循環(huán)取出參數(shù)列表中的參數(shù)并打印,這種方法要求在
            最后傳一個結(jié)束標志,比如"",代表空串.
            示例代碼如下:
      1. #include <stdio.h>  
      2. #include <stdlib.h>  
      3. #include <stdarg.h>  
      4.   
      5. void Manue (char* msg, ...) {  
      6.     va_list argp;  
      7.     char* para;  
      8.     printf("%s", msg);  
      9.     va_start(argp,msg);  
      10.   
      11.     while(1) {  
      12.         para = va_arg(argp, char *);  
      13.         if(strcmp(para, "")==0)  
      14.             break;  
      15.         printf("%s ", para);  
      16.     }  
      17.     va_end(argp);  
      18. }  
      19.   
      20. int main() {  
      21.   Manue("usage:", "file1", " file2", "");  
      22.   return 0;  
      23. }  
      二.第二種方法(有局限性,不過可以打印各種類型的參數(shù)):
          通過vsprintf函數(shù)格式化輸出各個參數(shù)到緩沖字符串.
         示例代碼如下:
      1. #include <stdio.h>  
      2. #include <stdlib.h>  
      3. #include <stdarg.h>  
      4. void PrintFError ( const char * format, ... )  
      5. {  
      6.   char buffer[256];  
      7.   va_list args;  
      8.   va_start (args, format);  
      9.   vsprintf (buffer,format, args);  
      10.   printf("%s\n", buffer);  
      11.   va_end (args);  
      12. }  
      13.   
      14. int main ()  
      15. {  
      16.   PrintFError ("%s%s%s", "usage:", "file1", " file2");  
      17.   return 0;  
      18. }  
      三.第三種方法(這種方法能打印同種類型的任意多個參數(shù)):
          以下示例代碼摘自W. Richard Stevens的<<TCP/IP詳解>>中使用
      的sock程序的代碼.巧妙地利用了這一點打印錯誤提示信息.
          代碼如下(為了演示,代碼略有修改):
      1. #include <stdio.h>  
      2. #include <stdlib.h>  
      3. #include <stdarg.h>  
      4. static void  
      5. err_doit(int errnoflag, const char *fmt, va_list ap)  
      6. {  
      7.     int     errno_save;  
      8.     char    buf[4096];  
      9.   
      10.     errno_save = errno;     /* value caller might want printed */  
      11.     vsprintf(buf, fmt, ap);  
      12.   
      13.     strcat(buf, "\n");  
      14.     fflush(stdout);     /* in case stdout and stderr are the same */  
      15.     fputs(buf, stderr);  
      16.     fflush(stderr);     /* SunOS 4.1.* doesn't grok NULL argument */  
      17.     return;  
      18. }  
      19.   
      20. void  
      21. /* $f err_msg $ */  
      22. err_msg(const char *fmt, ...)  
      23. {  
      24.     va_list     ap;  
      25.   
      26.     va_start(ap, fmt);  
      27.     err_doit(0, fmt, ap);  
      28.     va_end(ap);  
      29.     return;  
      30. }  
      31.   
      32. int main() {  
      33.     err_msg(  
      34. "usage: sock [ options ] <host> <port>              (for client; default)\n"  
      35. "       sock [ options ] -s [ <IPaddr> ] <port>     (for server)\n"  
      36. "       sock [ options ] -i <host> <port>           (for \"source\" client)\n"  
      37. "       sock [ options ] -i -s [ <IPaddr> ] <port>  (for \"sink\" server)\n"  
      38. "options: -b n  bind n as client's local port number\n"  
      39. "         -c    convert newline to CR/LF & vice versa\n"  
      40. "         -f a.b.c.d.p  foreign IP address = a.b.c.d, foreign port# = p\n"  
      41. "         -g a.b.c.d  loose source route\n"  
      42. "         -h    issue TCP half close on standard input EOF\n"  
      43. "         -i    \"source\" data to socket, \"sink\" data from socket (w/-s)\n"  
      44. #ifdef  IP_ADD_MEMBERSHIP  
      45. "         -j a.b.c.d  join multicast group\n"  
      46. #endif  
      47. "         -k    write or writev in chunks\n"  
      48. "         -l a.b.c.d.p  client's local IP address = a.b.c.d, local port# = p\n"  
      49. "         -n n  #buffers to write for \"source\" client (default 1024)\n"  
      50. "         -o    do NOT connect UDP client\n"  
      51. "         -p n  #ms to pause before each read or write (source/sink)\n"  
      52. "         -q n  size of listen queue for TCP server (default 5)\n"  
      53. "         -r n  #bytes per read() for \"sink\" server (default 1024)\n"  
      54. "         -s    operate as server instead of client\n"  
      55. #ifdef  IP_MULTICAST_TTL  
      56. "         -t n  set multicast ttl\n"  
      57. #endif  
      58. "         -u    use UDP instead of TCP\n"  
      59. "         -v    verbose\n"  
      60. "         -w n  #bytes per write() for \"source\" client (default 1024)\n"  
      61. "         -x n  #ms for SO_RCVTIMEO (receive timeout)\n"  
      62. "         -y n  #ms for SO_SNDTIMEO (send timeout)\n"  
      63. "         -A    SO_REUSEADDR option\n"  
      64. "         -B    SO_BROADCAST option\n"  
      65. "         -C    set terminal to cbreak mode\n"  
      66. "         -D    SO_DEBUG option\n"  
      67. "         -E    IP_RECVDSTADDR option\n"  
      68. "         -F    fork after connection accepted (TCP concurrent server)\n"  
      69. "         -G a.b.c.d  strict source route\n"  
      70. #ifdef  IP_TOS  
      71. "         -H n  IP_TOS option (16=min del, 8=max thru, 4=max rel, 2=min$)\n"  
      72. #endif  
      73. "         -I    SIGIO signal\n"  
      74. #ifdef  IP_TTL  
      75. "         -J n  IP_TTL option\n"  
      76. #endif  
      77. "         -K    SO_KEEPALIVE option\n"  
      78. "         -L n  SO_LINGER option, n = linger time\n"  
      79. "         -N    TCP_NODELAY option\n"  
      80. "         -O n  #ms to pause after listen, but before first accept\n"  
      81. "         -P n  #ms to pause before first read or write (source/sink)\n"  
      82. "         -Q n  #ms to pause after receiving FIN, but before close\n"  
      83. "         -R n  SO_RCVBUF option\n"  
      84. "         -S n  SO_SNDBUF option\n"  
      85. #ifdef  SO_REUSEPORT  
      86. "         -T    SO_REUSEPORT option\n"  
      87. #endif  
      88. "         -U n  enter urgent mode before write number n (source only)\n"  
      89. "         -V    use writev() instead of write(); enables -k too\n"  
      90. "         -W    ignore write errors for sink client\n"  
      91. "         -X n  TCP_MAXSEG option (set MSS)\n"  
      92. "         -Y    SO_DONTROUTE option\n"  
      93. "         -Z    MSG_PEEK\n"  
      94. #ifdef  IP_ONESBCAST  
      95. "         -2    IP_ONESBCAST option (255.255.255.255 for broadcast\n"  
      96. #endif  
      97. );  
      98.   return 0;  
      99. }  
       總結(jié):
          掌握了以上函數(shù)的用法后今后在寫程序中處理提示信息及幫助菜單的時候就可以直接運用,而不需要
      手動調(diào)用一堆printf函數(shù)打印.當(dāng)然還有更多的好處,比如第三中方法中的條件編譯導(dǎo)致參數(shù)的不確定性,這
      樣就可以直接用可變參數(shù)函數(shù)了.

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多