由於在C語言中沒有函數重載,解決不定數目函數參數問題變得比較麻煩。C語言中實現不定參數函數的問題是利用調用函數時使用的堆棧來解決。原理是通過堆棧讀取可選參數的值,直到讀取到所設定的結束標志為止。 下面程序的可選參數的結束標志設置為可選參數參數小於0。
在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)) ) //返回ap地址處的值,同時ap指向下一個可選參數的地址
#define va_end(ap) ( ap = (va_list)0 ) // 將指針置為無效
[cpp]
#include "stdafx.h"
#include "stdarg.h"
void test(int i,int j, ...)
{
int data;
va_list args; //定義va_list變量
printf("%d %d", i, j);
va_start(args,j); //使args指向j後的第一個可選參數
while((data = va_arg(args,int)) >= 0) //va_arg函數返回參數args指針所對應的變量值,同時args指向下個可選參<SPAN style="WHITE-SPACE: pre"> </SPAN>// 數. 參數大於或者等於0時,讀取數據,同時把讀取的數據打印出來。當讀<SPAN style="WHITE-SPACE: pre"> </SPAN> //到小於0的參數時,結束循環。
printf(" %d", data);
printf("\n");
va_end(args); //使args指針無效
}
int main(int argc, char* argv[])
{
test(0, 1 , 3, -1);
return 0;
}
#include "stdafx.h"
#include "stdarg.h"
void test(int i,int j, ...)
{
int data;
va_list args; //定義va_list變量
printf("%d %d", i, j);
va_start(args,j); //使args指向j後的第一個可選參數
while((data = va_arg(args,int)) >= 0) //va_arg函數返回參數args指針所對應的變量值,同時args指向下個可選參 // 數. 參數大於或者等於0時,讀取數據,同時把讀取的數據打印出來。當讀 //到小於0的參數時,結束循環。
printf(" %d", data);
printf("\n");
va_end(args); //使args指針無效
}
int main(int argc, char* argv[])
{
test(0, 1 , 3, -1);
return 0;
}[cpp] view plaincopyprint?//程序輸出結果為0 1 3
//程序輸出結果為0 1 3[cpp] view plaincopyprint?/*
main調用test函數堆棧的分布如下圖:
地址: 高 ...............
| ...............
| 第二個可選的參數
| 第一個可選的參數
| j
| i
低 test的返回地址
*/
/*
main調用test函數堆棧的分布如下圖:
地址: 高 ...............
| ...............
| 第二個可選的參數
| 第一個可選的參數
| j
| i
低 test的返回地址
*/
分享到: