当前位置:编程学习 > C/C++ >>

C语言变参函数的两个实现

作者:朱金灿

      国庆假期看了《程序员的自我修养——链接、装载和库》的大部分,其中P337提到了C语言变长参数的一些实现原理,书上的一个例子是(我对书上的代码作了一些小改动,书上的例子编译有点小问题):

 


#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
/*!
*  @brief 计算n个整数之和,这个暂时没有计算结果越界的问题
*
*  @param [in]num 要计算的整数个数
*  @return 计算结果
*/
long sum(int num,...)
{
    assert(num>0);
    int *p = &num+1;
 long ret = 0;
 while (num--)
 {
  ret +=*p++;
 }
 return ret;
}
 

 


      这里利用了函数的栈上的位置依次排列的原理(即不定参数的地址依次在变量num的高地址方向,同时函数调用约定采用的是cdecl)。下面是我参考MSDN实现和C语言的printf函数一样功能的MyPrintf函数:

 


/*!
*  @brief 格式化字符串输出到控制台
*
*  @param [in]pFormat 格式化字符串
*  @return 无
*/
void MyPrintf(TCHAR* pFormat, ... )
{
 va_list pArg;
 va_start(pArg, pFormat);
 int len;
 TCHAR* buffer;
len = _vsctprintf(pFormat,pArg )+ 1; // _vscprintf doesnt count, terminating
 buffer = (TCHAR*)(malloc(len * sizeof(TCHAR)));
 _vstprintf_s(buffer, len, pFormat,pArg);
 _putts( buffer );
 free( buffer );
 va_end(pArg); 
}
 

 


上面两个函数的测试代码:

 


int _tmain(int argc, _TCHAR* argv[])
{
    int x = 10;
 int y = 110;
 int z =200;
 long Ret = sum(3,x,y,z);
 MyPrintf(_T("%d %c %d"),123,<,456 );
 MyPrintf(_T("%s"),_T("This is a string"));
 getchar();
 return 0;
}
 


测试环境:Win XP + sp3, VS 2008 + sp1,unicode字符集。

 


参考文献:


1. 《程序员的自我修养--链接、装载和库》,俞甲子 / 石凡 / 潘爱民

2. MSDN(与VS 2008 + sp1配套)

 

 

 

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,