va_start

va_start,函式名稱,讀取可變參數的過程其實就是在堆疊中,使用指針,遍歷堆疊段中的參數列表,從低地址到高地址一個一個地把參數內容讀出來的過程·

基本介紹

  • 外文名:va_start
  • 類別:函式名稱
  • 使用範圍堆疊
  • 原因:在C語言中沒有函式重載
  • 頭檔案:stdarg.h
概述,代碼說明,參考資料,擴展閱讀,

概述

由於在C語言中沒有函式重載,解決不定數目函式參數問題變得比較麻煩;即使採用C++,如果參數個數不能確定,也很難採用函式重載.對這種情況,有些人採用指針參數來解決問題.下面就c語言中處理不定參數數目的問題進行討論
在VC++6.0的include有一個stdarg.h頭檔案,有如下幾個宏定義:
#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一個可選參數地址
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一個參數的值
#define va_end(ap) ( ap = (va_list)0 ) // 將指針置為無效
如果對以上幾個宏定義不理解,可以略過,接著看後面的內容.
在進程中,堆疊地址是從高到低分配的.當執行一個函式的時候,將參數列表入棧,壓入堆疊的高地址部分,然後入棧函式的返回地址,接著入棧函式的執行代碼,這個入棧過程,堆疊地址不斷遞減,一些黑客就是在堆疊中修改函式返回地址,執行自己的代碼來達到執行自己插入的代碼段的目的.
總之,函式在堆疊中的分布情況是:地址從高到低,依次是:函式參數列表,函式返回地址,函式執行代碼段.
堆疊中,各個函式的分布情況是倒序的.即最後一個參數在列表中地址最高部分,第一個參數在列表地址的最低部分.參數在堆疊中的分布情況如下:
最後一個參數
倒數第二個參數
...
第一個參數
函式返回地址
函式代碼段

代碼說明

void arg_test(int i, ...);
int main(int argc,char *argv[])
{
int int_size = _INTSIZEOF(int);
printf("int_size=%d\n", int_size);
arg_test(0, 4);
//arg_cnt(4,1,2,3,4);
return 0;
}
void arg_test(int i, ...)
{
int j=0;
va_list arg_ptr;
va_start(arg_ptr, i);
printf("&i = %p\n", &i);//列印參數i在堆疊中的地址

相關詞條

熱門詞條

聯絡我們