最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于C/C++中可變參數(shù)的詳細(xì)介紹(va_list,va_start,va_arg,va_end)

 更新時(shí)間:2013年10月03日 09:26:09   作者:  
可變參數(shù)的函數(shù)原理其實(shí)很簡單,而va系列是以宏定義來定義的,實(shí)現(xiàn)跟堆棧相關(guān).我們寫一個(gè)可變函數(shù)的C函數(shù)時(shí),有利也有弊,所以在不必要的場合,我們無需用到可變參數(shù)。如果在C++里,我們應(yīng)該利用C++的多態(tài)性來實(shí)現(xiàn)可變參數(shù)的功能,盡量避免用C語言的方式來實(shí)現(xiàn)

由于在C語言中沒有函數(shù)重載,解決不定數(shù)目函數(shù)參數(shù)問題變得比較麻煩,即使采用C++,如果參數(shù)個(gè)數(shù)不能確定,也很難采用函數(shù)重載。對這種情況,提出了指針參數(shù)來解決問題。

如printf()函數(shù),其原型為:
int   printf(   const   char*   format,   ...);

它除了有一個(gè)參數(shù)format固定以外,后面跟的參數(shù)的個(gè)數(shù)和類型是可變的,例如我們可以有以下不同的調(diào)用方法:  
printf( "%d ",i);  
printf( "%s ",s);  
printf( "the   number   is   %d   ,string   is:%s ",   i,   s);  

如何實(shí)現(xiàn)其功能?

我們需要以下幾個(gè)宏定義:

(1)va_list
定義了一個(gè)指針arg_ptr, 用于指示可選的參數(shù).

(2)va_start(arg_ptr, argN)
使參數(shù)列表指針arg_ptr指向函數(shù)參數(shù)列表中的第一個(gè)可選參數(shù),argN是位于第一個(gè)可選參數(shù)之前的固定參數(shù), 或者說最后一個(gè)固定參數(shù).如有一va函數(shù)的聲明是void va_test(char a, char b, char c, ...), 則它的固定參數(shù)依次是a,b,c, 最后一個(gè)固定參數(shù)argN為c, 因此就是va_start(arg_ptr, c).

(3)va_arg(arg_ptr, type)
返回參數(shù)列表中指針arg_ptr所指的參數(shù), 返回類型為type. 并使指針arg_ptr指向參數(shù)列表中下一個(gè)參數(shù).返回的是可選參數(shù), 不包括固定參數(shù).

(4)va_end(arg_ptr)
清空參數(shù)列表, 并置參數(shù)指針arg_ptr無效.

(注:va在這里是variable-argument(可變參數(shù))的意思.   這些宏定義在stdarg.h中,所以用到可變參數(shù)的程序應(yīng)該包含這個(gè)頭文件)

也需你現(xiàn)在還是不能理解,別著急,現(xiàn)在從一個(gè)實(shí)例著手.定義這么一個(gè)函數(shù),函數(shù)的第一個(gè)參數(shù)是固定的,其余參數(shù)是可變的。定義為:
void   simple_va_fun(int i,...); 其代碼為:

復(fù)制代碼 代碼如下:

#include <iostream>
#include <stdarg.h>
using namespace std;
void simple_va_fun(int i,...);

int main(int argc,char *argv[])
{
    simple_va_fun(100);  
    simple_va_fun(100,200);
    simple_va_fun(100,200,'a');
    return 0;
}

void simple_va_fun(int i,...)  
{  
    va_list   arg_ptr;   //定義可變參數(shù)指針
    va_start(arg_ptr,i);   // i為最后一個(gè)固定參數(shù)
    int j=va_arg(arg_ptr,int);   //返回第一個(gè)可變參數(shù),類型為int
    char c=va_arg(arg_ptr,char);   //返回第二個(gè)可變參數(shù),類型為char
    va_end(arg_ptr);        //  清空參數(shù)指針
    printf( "%d %d %c\n",i,j,c);  
    return;  
}


代碼運(yùn)行解釋:  
(1)首先在函數(shù)里定義一個(gè)va_list型的變量,這里是arg_ptr,這個(gè)變量是指向參數(shù)的指針.

(2)然后用va_start宏初始化變量arg_ptr,這個(gè)宏的第二個(gè)參數(shù)是第一個(gè)可變參數(shù)的前一個(gè)參數(shù),是一個(gè)固定的參數(shù).

(3)然后用va_arg返回第一個(gè)可變的參數(shù),并賦值給整數(shù)j。va_arg的第二個(gè)參數(shù)是你要返回的參數(shù)的類型,這里是int型.  返回第一個(gè)可變參數(shù)后arg_ptr指向第二個(gè)可變參數(shù),用同樣的方法返回并賦值給c,類型為char類型。

(4)最后用va_end宏結(jié)束可變參數(shù)的獲取。

小結(jié):
可變參數(shù)的函數(shù)原理其實(shí)很簡單,而va系列是以宏定義來定義的,實(shí)現(xiàn)跟堆棧相關(guān).我們寫一個(gè)可變函數(shù)的C函數(shù)時(shí),有利也有弊,所以在不必要的場合,我們無需用到可變參數(shù).如果在C++里,我們應(yīng)該利用C++的多態(tài)性來實(shí)現(xiàn)可變參數(shù)的功能,盡量避免用C語言的方式來實(shí)現(xiàn)。

附加:

參數(shù)在堆棧中分布:
在進(jìn)程中,堆棧地址是從高到低分配的.當(dāng)執(zhí)行一個(gè)函數(shù)的時(shí)候,將參數(shù)列表入棧,壓入堆棧的高地址部分,然后入棧函數(shù)的返回地址,接著入棧函數(shù)的執(zhí)行代碼,這個(gè)入棧過程,堆棧地址不斷遞減,一些黑客就是在堆棧中修改函數(shù)返回地址,執(zhí)行自己的代碼來達(dá)到執(zhí)行自己插入的代碼段的目的. 總之,函數(shù)在堆棧中的分布情況是:地址從高到低,依次是:函數(shù)參數(shù)列表,函數(shù)返回地址,函數(shù)執(zhí)行代碼段. 堆棧中,各個(gè)函數(shù)的分布情況是倒序的.即最后一個(gè)參數(shù)在列表中地址最高部分,第一個(gè)參數(shù)在列表地址的最低部分.參數(shù)在堆棧中的分布情況如下:

最后一個(gè)參數(shù)
倒數(shù)第二個(gè)參數(shù)
...
第一個(gè)參數(shù)
函數(shù)返回地址
函數(shù)代碼段

相關(guān)文章

  • 詳解C/C++性能優(yōu)化背后的方法論TMAM

    詳解C/C++性能優(yōu)化背后的方法論TMAM

    開發(fā)過程中我們多少都會關(guān)注服務(wù)的性能,然而性能優(yōu)化是相對比較困難,往往需要多輪優(yōu)化、測試,屬于費(fèi)時(shí)費(fèi)力,有時(shí)候還未必有好的效果。但是如果有較好的性能優(yōu)化方法指導(dǎo)、工具輔助分析可以幫助我們快速發(fā)現(xiàn)性能瓶頸所在,針對性地進(jìn)行優(yōu)化,可以事半功倍
    2021-06-06
  • C語言版實(shí)現(xiàn)三子棋游戲

    C語言版實(shí)現(xiàn)三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語言版實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C++ 獲取dll當(dāng)前路徑下所有文件

    C++ 獲取dll當(dāng)前路徑下所有文件

    本文主要介紹了C++ 獲取dll當(dāng)前路徑下所有文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • C++ 通過指針實(shí)現(xiàn)多態(tài)實(shí)例詳解

    C++ 通過指針實(shí)現(xiàn)多態(tài)實(shí)例詳解

    這篇文章主要介紹了 C++ 通過指針實(shí)現(xiàn)多態(tài)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 理解C++編程中的std::function函數(shù)封裝

    理解C++編程中的std::function函數(shù)封裝

    這篇文章主要介紹了理解C++編程中的std::function函數(shù)封裝,std::function是C++11標(biāo)準(zhǔn)中的新特性,需要的朋友可以參考下
    2016-04-04
  • 聊一聊OpenCV相機(jī)標(biāo)定

    聊一聊OpenCV相機(jī)標(biāo)定

    這篇文章主要為大家詳細(xì)介紹了OpenCV相機(jī)標(biāo)定的相關(guān)資料,即獲得相機(jī)參數(shù)的過程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++中隊(duì)列queue的用法實(shí)例詳解

    C++中隊(duì)列queue的用法實(shí)例詳解

    隊(duì)列先進(jìn)先出,即只能在容器的末尾添加新元素,只能從頭部移除元素,下面這篇文章主要給大家介紹了關(guān)于C++中隊(duì)列queue用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • C++中IO多路復(fù)用(select、poll、epoll)的實(shí)現(xiàn)

    C++中IO多路復(fù)用(select、poll、epoll)的實(shí)現(xiàn)

    I/O多路復(fù)用是一種并發(fā)處理多個(gè)I/O操作的機(jī)制,本文主要介紹了C++中IO多路復(fù)用(select、poll、epoll)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • C語言中#define與typedef的互換細(xì)節(jié)詳解

    C語言中#define與typedef的互換細(xì)節(jié)詳解

    本篇文章是對C語言中#define與typedef的互換細(xì)節(jié)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 簡單談?wù)勱P(guān)于C++中大隨機(jī)數(shù)的問題

    簡單談?wù)勱P(guān)于C++中大隨機(jī)數(shù)的問題

    這篇文章主要介紹了關(guān)于C++中大隨機(jī)數(shù)的問題,文中給出了詳細(xì)的示例代碼,相信對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價(jià)值,有需要的朋友可以一起來學(xué)習(xí)學(xué)習(xí)。
    2017-01-01

最新評論

瑞安市| 瓮安县| 新竹县| 隆昌县| 海伦市| 安阳市| 阳新县| 凤庆县| 勐海县| 临桂县| 阳谷县| 工布江达县| 太白县| 仁化县| 唐河县| 阿巴嘎旗| 扬中市| 黄石市| 方山县| 平陆县| 白朗县| 郑州市| 河源市| 抚松县| 于田县| 墨江| 新密市| 台东市| 沭阳县| 威信县| 兴城市| 光泽县| 扬州市| 蓬溪县| 英吉沙县| 上高县| 乐业县| 建宁县| 平昌县| 洛扎县| 鄯善县|