不定参数函数的运用与实现

在论坛里看了“printf("%f",10/3); 答案是多少?”这篇帖子后,自己写了下小结!!望大家不吝赐教!!!

 

 

实现原理和理论依据:

      函数参数传递的时候,参数是线性的存储在内存中的,因此,如果知道参数存放的起始位置和结束位置,和参数的类型,那么就可以得到需要的所有参数.

关于不定参数头文件stdarg.h中的几个宏定义(每一个颜色板块为一个宏定义及其解释):

va_list:

#ifndef _VA_LIST_DEFINED
#ifdef  _M_ALPHA
typedef struct {
        char *a0;       /* pointer to first homed integer argument */
        int offset;     /* byte offset of next parameter */
} va_list;
#else
typedef char *  va_list;
#endif
#define _VA_LIST_DEFINED
#endif


 

其中a0或者va_list是第一个参数的地址,offset是从第一个参数到第二个参数的内存地址偏移量,由参数的类型占用内存的空间决定.

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )


 

得到参数n的尺寸,相当与sizeof(n),为了兼容性写成了如上的表达式.

#define va_start(ap,v)  ( ap = (va_list)&v + _INTSIZEOF(v) )


 

其中ap是一个va_list型的参数列表指针变量,v是参数表中的第一个参数的名字.作用是初始化参数表,并让参数表指针ap指向参数列表的第二个参数开始地址(根据以上宏定义的表达式得知).

 

#define va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )


根据参数类型移动参数表指针ap,使之返回下一个参数的值,参数的类型由第二个参数t指定(分析以上宏定义表达式).

#define va_end(ap)      ( ap = (va_list)0 )


 

结束参数传递,做清理工作,即让参数表指针清空.

 

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

int sum(int first,...)///* 函数原型声明,至少需要一个确定的参数,注意括号内的省略号 */
{
	va_list ap;//定义保存函数参数的结构
	va_start (ap,first);//初始化参数表,并让参数表指针ap指向参数列表的第二个参数开始地址

	int sum=first;
	
	while (va_arg(ap,int))//以0结束
	{
		sum+=va_arg(ap,int);//根据参数类型移动参数表指针ap,使之返回下一个参数的值
	}
	va_end(ap);
	return sum;
}

int main()
{
	printf ("%d\n",sum(1,2,3,4,5,6,7,0));
	system("pause");
	return 0;
}


 

 

 

 

运用优劣参考 链接

 

 

 

 

你可能感兴趣的:(一些常识)