程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 關於C/C++中可變參數的具體引見(va_list,va_start,va_arg,va_end)

關於C/C++中可變參數的具體引見(va_list,va_start,va_arg,va_end)

編輯:關於C++

關於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說話的方法來完成。

附加:

參數在客棧平分布:
在過程中,客棧地址是從高到低分派的.當履行一個函數的時刻,將參數列表入棧,壓入客棧的窪地址部門,然後入棧函數的前往地址,接著入棧函數的履行代碼,這個入棧進程,客棧地址赓續遞加,一些黑客就是在客棧中修正函數前往地址,履行本身的代碼來到達履行本身拔出的代碼段的目標. 總之,函數在客棧中的散布情形是:地址從高到低,順次是:函數參數列表,函數前往地址,函數履行代碼段. 客棧中,各個函數的散布情形是倒序的.即最初一個參數在列表中地址最高部門,第一個參數在列表地址的最低部門.參數在客棧中的散布情形以下:

最初一個參數
倒數第二個參數
...
第一個參數
函數前往地址
函數代碼段

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved