程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 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配套)

 

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved