C/C++函数变长参数列表实现

在C编译器通常提供了一系列处理可变参数的 ,实现就像printf()那样的变长参数列表,这样可以屏蔽不同的硬件平台造成的差异,增加程序的可移植性。这些宏包括 va_startva_argva_end等,这些宏都是在头文件 <stdarg.h>里定义的。
采用ANSI标准形式时, 参数个数可变的函数原型声明是:
type funcname(type para1, type para2, ...)
这种形式 至少需要一个普通的形式参数,后面的省略号不表示省略,而是函数原型的一部分。type是函数返回值和形式参数的类型。

不同的编译器,对这个可变长参数的实现不一样 ,gcc4.x中是采用内置函数的方法来实现。

 

接下来我们看看以下示例代码:

#include <stdarg.h>
#include <stdio.h>

 

int Sum (int n, ...)
{
int sum = 0, i = 0;
va_list p; // 定义一个变量 ,保存函数参数列表的指针。

va_start(p, n); // 用va_start宏初始化变量p,
// va_start宏的第2个参数n,
// 是一个固定的参数,
// 必须是我们自己定义的变长函数的最后一个入栈的参数,
// 也就是调用的时候参数列表里的第1个参数。

for (i = 1; i < n; ++ i) // i从1开始,遍历所有可变参数。
{
sum += va_arg(p, int); // va_arg取出当前的参数,

// 并认为取出的参数是一个整数(int) 。
}

return sum;
}

 

int main(void)
{
int num;
num = Sum(5, 1, 2, 3, 4);
printf("%d/n", num);
return 0;
}

 

当我们调用Sum函数时,传递给Sum函数的参数列表的第一个参数n的值是5,va_start 初始化p使其指向第一个未命名的参数(n是有名字的参数) ,也就是1(第一个),每次对 va_arg的调用,都将返回一个参数,并且把 p 指向下一个参数,va_arg 用一个类型名来决定返回的参数是何种类型,以及在 var_arg的内部实现中决定移动多大的距离才到达下一个参数。

 

==========================================================================

void AddText(HWND hWndLB, PCTSTR pszFormat, ...) {

va_list argList;
va_start(argList, pszFormat);

TCHAR sz[20 * 1024];
_vstprintf_s(sz, _countof(sz), pszFormat, argList);
    
cout<<sz;

va_end(argList);
}

AddText(NULL, TEXT("[%d] Nothing to process"), num);

 

你可能感兴趣的:(c,list,gcc,null,平台,编译器)