库函数模拟(二),可变参数列表

我们将实现printf的模拟。在这之前,先总结可变参数列表的有关知识点~

在函数原型中,列出了函数期望的参数,但原型只能显示固定数目的参数。其实,让一个函数接收不同数目的参数也

是可以的。可变参数列表是通过宏来实现,这些宏定义于stdarg.h文件,它是标准库的一部分。这个头文件声明了一

个类型va_list和三个宏——va_start、va_arg、va_end.在编译器下,我们通过查看定义来理解和明白这些宏和类型

到底是表示什么。

VC6.0下对他们的定义如图所示~

va_list是char类型的指针~

va_start是用来初试化arg,找到未知参数的第一个参数的地址

va_arg是用于遍历未知参数的每个参数,每一次我们找一个参数时,arg指针都会指向该参数的下一个位置~所以我

          们不要连着使用这个宏,比如,当我们要找参数的最大值时,应该讲参数保存起来,而不是比较完了之后发 

            现需 要这 个参数,再利用va_start来找,这样就会漏过一些参数~库函数模拟(二),可变参数列表_第1张图片

va_end把arg赋值为空,这个是必须要进行的操作~

下面我们利用可变参数列表来实现printf函数的模拟~

void print(char *format, ...)
{
	va_list arg;
	va_start(arg,format);
	char c;
	char *str;
	while (*format)
	{
		switch (*format)
		{
		case 'c':
		{
			c = va_arg(arg,char);
			putchar(c);
		}break;
		case 's':
		{
			str = va_arg(arg,char*);
			//puts(str);
			while (*str)
			{
				putchar(*str);
				str++;
			}
		}break;
		default:
			putchar(*format);

		}format++;
	}
	
	va_end(arg);
}
int main()
{
	print("s ccc.\n","hello",'b','i','t');
	system("pause");
	return 0;
}
代码分析:函数实现中,使用switch,case语句比if,else能好一些,至少结构上更清晰一点~printf模拟实现并不

是真正的模拟,在库函数里printf的第一个参数是%s,%c等等这种,而我模拟实现时 ,默认看到s就是输出字符串

,要想完全模拟库函数,还需要利用字符串的知识完成~还有,在输出字符串时,不要使用puts函数一次打印出字

符串,因为puts在输出完一个字符串时,会自动输出一个回车,所以我们需要while循环一个字符一个字符的输

出。

可变参数的限制:

    1.至少要有一个参数~要是没有的话,怎么找到后边参数的地址呀??~

    2.宏无法判断参数个数~

   3.宏无法判断参数类型~

   4.如果va_arg指定了错误类型,后果比较严重~



你可能感兴趣的:(库函数模拟(二),可变参数列表)