<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      pBendan

      導航

      [轉載]va_start和va_end使用詳解

      va_start和va_end使用詳解

      原文地址:http://www.rzrgm.cn/hanyonglu/archive/2011/05/07/2039916.html

      本文主要介紹va_start和va_end的使用及原理。

        在以前的一篇帖子Format MessageBox 詳解中曾使用到va_start和va_end這兩個宏,但對它們也只是泛泛的了解。

        介紹這兩個宏之前先看一下C中傳遞函數的參數時的用法和原理:

      1.在C中,當我們無法列出傳遞函數的所有實參的類型和數目時,可以用省略號指定參數表

      void foo(...); void foo(parm_list,...);
      這種方式和我們以前認識的不大一樣,但我們要記住這是C中一種傳參的形式,在后面我們就會用到它。

       

      2.函數參數的傳遞原理

        函數參數是以數據結構:棧的形式存取,從右至左入棧。

        首先是參數的內存存放格式:參數存放在內存的堆棧段中,在執行函數的時候,從最后一個開始入棧。因此棧底高地址,棧頂低地址,舉個例子如下: void func(int x, float y, char z);   那么,調用函數的時候,實參 char z 先進棧,然后是 float y,最后是 int x,因此在內存中變量的存放次序是 x->y->z,因此,從理論上說,我們只要探測到任意一個變量的地址,并且知道其他變量的類型,通過指針移位運算,則總可以順藤摸瓜找到其他的輸入變量。
        下面是 <stdarg.h> 里面重要的幾個宏定義如下: typedef char* va_list; void va_start ( va_list ap, prev_param ); /* ANSI version */ type va_arg ( va_list ap, type ); void va_end ( va_list ap ); va_list 是一個字符指針,可以理解為指向當前參數的一個指針,取參必須通過這個指針進行。 <Step 1> 在調用參數表之前,定義一個 va_list 類型的變量,(假設va_list 類型變量被定義為ap); <Step 2> 然后應該對ap 進行初始化,讓它指向可變參數表里面的第一個參數,這是通過 va_start 來實現的,第一個參數是 ap 本身,第二個參數是在變參表前面緊挨著的一個變量,即“...”之前的那個參數; <Step 3> 然后是獲取參數,調用va_arg,它的第一個參數是ap,第二個參數是要獲取的參數的指定類型,然后返回這個指定類型的值,并且把 ap 的位置指向變參表的下一個變量位置; <Step 4> 獲取所有的參數之后,我們有必要將這個 ap 指針關掉,以免發生危險,方法是調用 va_end,他是輸入的參數 ap 置為 NULL,應該養成獲取完參數表之后關閉指針的習慣。說白了,就是讓我們的程序具有健壯性。通常va_start和va_end是成對出現。
      例如 int max(int n, ...); 其函數內部應該如此實現:
      #include <iostream.h>
      void fun(int a, ...)
      {   
        int *temp = &a;
        temp++;

        for (int i = 0; i < a; ++i)   

        {     

          cout << *temp << endl;     

          temp++;   

        }

      }

      int main()

      {

        int a = 1;

        int b = 2;

        int c = 3;

        int d = 4;

        fun(4, a, b, c, d);

        system("pause");

        return 0;

      }

      Output:: 1 2 3 4

      3:獲取省略號指定的參數   在函數體中聲明一個va_list,然后用va_start函數來獲取參數列表中的參數,使用完畢后調用va_end()結束。像這段代碼: void TestFun(char* pszDest, int DestLen, const char* pszFormat, ...) { va_list args; va_start(args, pszFormat); //一定要“...”之前的那個參數 _vsnprintf(pszDest, DestLen, pszFormat, args); va_end(args); }
       
      4.演示如何使用參數個數可變的函數,采用ANSI標準形式
      #include 〈stdio.h〉
      #include 〈string.h〉
      #include 〈stdarg.h〉
      /*函數原型聲明,至少需要一個確定的參數,注意括號內的省略號*/
      int demo( char, ... );
      void main( void )
      {
         demo("DEMO", "This", "is", "a", "demo!", "");
      }
      /*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);
            if ( strcmp( para, "") == 0 )
                 break;
             printf("Parameter #%d is: %s\n", argno, para);
             argno++;
       }
      va_end( argp );
      /*將argp置為NULL*/
      return 0;
      }

       以上是對va_start和va_end的介紹。

      posted on 2015-06-18 10:28  pBendan  閱讀(191)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 起碰免费公开97在线视频| 色九月亚洲综合网| 久久天天躁夜夜躁狠狠ds005| 亚洲欧美自偷自拍视频图片| 国产成人一卡2卡3卡四卡视频| 在线亚洲妇色中文色综合| 无码内射中文字幕岛国片 | 精品无码国产日韩制服丝袜| 国产精品国产三级国产试看| 国产97视频人人做人人爱| 国产女精品视频网站免费| 亚洲中文欧美在线视频| 日本精品不卡一二三区| √天堂资源网最新版在线| 亚洲精品一二三四区| 国产午夜福利视频第三区| 无码人妻丝袜在线视频| 国产中文三级全黄| 欧美色欧美亚洲高清在线观看| 好吊妞人成视频在线观看| 井研县| 日本一区午夜艳熟免费| 99久久精品费精品国产一区二| 日本无遮挡吸乳视频| 色天使亚洲综合一区二区| 精品中文字幕人妻一二| 日韩精品一区二区三区视频| 少妇人妻真实偷人精品| 国产欧美综合在线观看第十页| 中文字幕无码免费久久| 亚洲一精品一区二区三区| av色国产色拍| 人人妻人人插视频| 97精品久久天干天天天按摩| 国产一区日韩二区三区| 六枝特区| 人人入人人爱| 欧美极品色午夜在线视频| 成人免费乱码大片a毛片| 亚洲无人区码二码三码区| 女人被爽到高潮视频免费国产 |