type va_arg( va_list arg_ptr, type );
void va_end( va_list arg_ptr );
假定函数含有一个必选参数和多个可选参数 , 必选参数声明为普通数据类型,且能通过参数名来获得该变量的值 。可选参数通过宏va_start、va_arg和va_end(定义在stdarg.h或varargs.h中)来进行操作,即通过设置指向第一个可选参数指针、返回当前参数、在返回参数后重新设置指针来操作所有的可选参数 。
va_start:为获取可变数目参数的函数的参数提供一种便捷手段 。设置arg_ptr为指向传给函数参数列表中的第一个可选参数的指针,且该参数必须是va_list类型 。prev_param是在参数列表中第一个可选参数前的必选参数 。
va_arg如何写c语言函数库:返回由arg_ptr所指向的参数的值,且自增指向下一个参数的地址 。type为当前参数的类型 , 用来计算该参数的长度,确定下一个参数的起始位置 。它可以在函数中应用多次,直到得到函数的所有参数为止,但必须在宏va_start后面调用 。
va_end:在获取所有的参数后 , 设置指针arg_ptr为NULL 。
下面举例说明如何写c语言函数库:
#include
#include
int average( int first, ... );
void main( void )
{
/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );
/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );
/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}
int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;
va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}
返回值为:
Average is: 3
Average is: 8
Average is: 0
综上所述,在printf()函数中 , 可以只输出一个字符串,也可按照一定的形式输出含有多个可选参数的字符串信息 。因此,首先就要通过这些宏来获取所有的可选参数 。在上面的源码可以看出printf()中 , 只使用了宏at_start,将可选参数的首地址赋给了arglist 。
2、锁定字符串及输出字符串到屏幕
#define _lock_str2(i,s) _lock_file2(i,s)
void __cdecl _lock_file2(int, void *);
#define _unlock_str2(i,s) _unlock_file2(i,s)
void __cdecl _unlock_file2(int, void *);
int __cdecl _stbuf(FILE *);
void __cdecl _ftbuf(int, FILE *);
int __cdecl _output(FILE *, const char *, va_list);
在output函数中 , 读取格式字符串中的每一个字符,然后对其进行处理,处理方式根据每一个字符所代表的意义来进行,如:普通字符直接利用函数WRITE_CHAR(ch, charsout);输出到控制台 。
其中的主要部分是对转换说明符(d,c,s,f)的处理,现在将对其中的部分代码进行详细说明,这里只说明最基本的转换说明符,对这些须基本的转换说明符进行修饰的修饰符 , 程序中单独进行处理 。下面是函数output()(output.c)部分源代码:
case ST_TYPE:
//表示当前处理的字符的类型为转换说明符 。
...
switch (ch) {
//下面对参数的获取都是利用宏va_arg( va_list arg_ptr, type );来进行的 。
case ''c'': {
//从参数表中获取单个字符 , 输出到缓冲字符串中,此时,type=int
buffer[0] = (char) get_int_arg(argptr); /* get char to print */
text = buffer;
textlen = 1; /* print just a single character */
}
break;
case ''s'': {
//从参数表中获取字符串,输出到缓冲字符串中 , 此时,type=char*
推荐阅读
- 什么样的风景值得拍摄呢,拍风景选择什么相机
- thinkphp6手册手机,thinkphp31手册
- 民间实用格斗游戏,民间实用格斗游戏视频
- 明日之后ios版在哪里兑换,明日之后苹果用户怎么兑换礼包
- linux怎么保存命令行 linux命令 保存
- sqlite更新数据python的简单介绍
- 老板角色扮演单机游戏,角色扮演领导员工游戏
- chatgpt最被低估的球员,十大被低估球员
- mysql百分比怎么表示 mysql百分数怎么表示