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

作者:朱金灿
来源:http://blog.csdn.net/clever101/


      国庆假期看了《程序员的自我修养——链接、装载和库》的大部分,其中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 doesn't count, terminating '/0' 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语言变参函数的两个实现)