c语言制作函数库 c语言的库函数源码( 二 )


* Uses temporary buffering to improve efficiency.
* _output does the real work here
*
*Entry:
* char *format - format string to control data format/number of arguments
* followed by list of arguments, number and type controlled by
* format string
*
*Exit:
* returns number of characters printed
*
*Exceptions:
*
*******************************************************************************/
int __cdecl printf (
const char *format,
...
)
/*
* stdout ''PRINT'', ''F''ormatted
*/
{
va_list arglist;
int buffing;
int retval;
va_start(arglist, format);
_ASSERTE(format != NULL);//断言宏 。如果输出格式字符串指针为空,则在DEBUG版下断言,报告错误 。
_lock_str2(1, stdout);
buffing = _stbuf(stdout);//stdout:指定输出到屏幕
retval = _output(stdout,format,arglist);
_ftbuf(buffing, stdout);
_unlock_str2(1, stdout);
return(retval);
}
以上为printf()的源代码
1、从含有可选参数函数中获得可选参数,以及操作这些参数
typedef char *va_list;
void va_start( va_list arg_ptr, prev_param );
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:返回由arg_ptr所指向的参数的值 , 且自增指向下一个参数的地址 。type为当前参数的类型,用来计算该参数的长度 , 确定下一个参数的起始位置 。它可以在函数中应用多次,直到得到函数的所有参数为止,但必须在宏va_start后面调用 。
va_end:在获取所有的参数后,设置指针arg_ptr为NULL 。
下面举例说明:
#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
【c语言制作函数库 c语言的库函数源码】综上所述,在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 *);

推荐阅读