關於C/C++中可變參數的具體引見(va_list,va_start,va_arg,va_end)。本站提示廣大學習愛好者:(關於C/C++中可變參數的具體引見(va_list,va_start,va_arg,va_end))文章只能為提供參考,不一定能成為您想要的結果。以下是關於C/C++中可變參數的具體引見(va_list,va_start,va_arg,va_end)正文
因為在C說話中沒有函數重載,處理不定命目函數參數成績變得比擬費事,即便采取C++,假如參數個數不克不及肯定,也很難采取函數重載。對這類情形,提出了指針參數來處理成績。
如printf()函數,其原型為:
int printf( const char* format, ...);
它除有一個參數format固定之外,前面跟的參數的個數和類型是可變的,例如我們可以有以下分歧的挪用辦法:
printf( "%d ",i);
printf( "%s ",s);
printf( "the number is %d ,string is:%s ", i, s);
若何完成其功效?
我們須要以下幾個宏界說:
(1)va_list
界說了一個指針arg_ptr, 用於指導可選的參數.
(2)va_start(arg_ptr, argN)
使參數列表指針arg_ptr指向函數參數列表中的第一個可選參數,argN是位於第一個可選參數之前的固定參數, 或許說最初一個固定參數.若有一va函數的聲明是void va_test(char a, char b, char c, ...), 則它的固定參數順次是a,b,c, 最初一個固定參數argN為c, 是以就是va_start(arg_ptr, c).
(3)va_arg(arg_ptr, type)
前往參數列表中指針arg_ptr所指的參數, 前往類型為type. 並使指針arg_ptr指向參數列表中下一個參數.前往的是可選參數, 不包含固定參數.
(4)va_end(arg_ptr)
清空參數列表, 並置參數指針arg_ptr有效.
(注:va在這裡是variable-argument(可變參數)的意思. 這些宏界說在stdarg.h中,所以用到可變參數的法式應當包括這個頭文件)
也需你如今照樣不克不及懂得,別焦急,如今從一個實例著手.界說這麼一個函數,函數的第一個參數是固定的,其他參數是可變的。界說為:
void simple_va_fun(int i,...); 其代碼為:
#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; //界說可變參數指針
va_start(arg_ptr,i); // i為最初一個固定參數
int j=va_arg(arg_ptr,int); //前往第一個可變參數,類型為int
char c=va_arg(arg_ptr,char); //前往第二個可變參數,類型為char
va_end(arg_ptr); // 清空參數指針
printf( "%d %d %c\n",i,j,c);
return;
}
代碼運轉說明:
(1)起首在函數裡界說一個va_list型的變量,這裡是arg_ptr,這個變量是指向參數的指針.
(2)然後用va_start宏初始化變量arg_ptr,這個宏的第二個參數是第一個可變參數的前一個參數,是一個固定的參數.
(3)然後用va_arg前往第一個可變的參數,並賦值給整數j。va_arg的第二個參數是你要前往的參數的類型,這裡是int型. 前往第一個可變參數後arg_ptr指向第二個可變參數,用異樣的辦法前往並賦值給c,類型為char類型。
(4)最初用va_end宏停止可變參數的獲得。
小結:
可變參數的函數道理其實很簡略,而va系列是以宏界說來界說的,完成跟客棧相干.我們寫一個可變函數的C函數時,有益也有弊,所以在不用要的場所,我們無需用到可變參數.假如在C++裡,我們應當應用C++的多態性來完成可變參數的功效,盡可能防止用C說話的方法來完成。
附加:
參數在客棧平分布:
在過程中,客棧地址是從高到低分派的.當履行一個函數的時刻,將參數列表入棧,壓入客棧的窪地址部門,然後入棧函數的前往地址,接著入棧函數的履行代碼,這個入棧進程,客棧地址赓續遞加,一些黑客就是在客棧中修正函數前往地址,履行本身的代碼來到達履行本身拔出的代碼段的目標. 總之,函數在客棧中的散布情形是:地址從高到低,順次是:函數參數列表,函數前往地址,函數履行代碼段. 客棧中,各個函數的散布情形是倒序的.即最初一個參數在列表中地址最高部門,第一個參數在列表地址的最低部門.參數在客棧中的散布情形以下:
最初一個參數
倒數第二個參數
...
第一個參數
函數前往地址
函數代碼段