模拟printf函数,//print("val:s ccccc\n","hello", 'w,'o','r','l','d'); //val:hello world(可变参数列表)

可变参数函数顾名思义,就是函数参数个数是未知的是可变的。

可变参数列表是通过宏来实现的,这些宏定义在stdarg.h 这个头文件中,这个头文件声明了一个类型va_list和三个宏——va_start , va_arg,  va_end.

 
 

我们可以通过声明一个类型为va_list的变量,与这三个宏配合使用,从而访问参数的值,

用法:

比如定义一个可变参数函数

void print(char *fomt, ...)

va_list : 声明一个变量//va_list arg;

va_start:初始化va_list声明的这个变量,它的第一个参数是va_list声明的变量另外一个参数是省略号前最后一个有名字的参数//va_start(arg,fomt);

初始化过程就是把参数列表的第一个参数给va_list声明的这个变量。

va_arg:我们就是通过这个来访问未知参数的,va_arg的一个参数是va_list声明的这个变量,另一个参数列表中下一个要接收的参数类型//va_arg(arg,char);

va_end:释放空间

下面我们就通过模拟printf这个函数,来具体了解。

#include<stdio.h>
#include<assert.h>
#include<stdarg.h>
void print(char *fomt, ...)
{
	char *ch;
	assert(*fomt);//断言
	va_list arg;//定义arg
	va_start(arg, fomt);初始化arg 即把可变参数列表中首个变量地址给arg
	while (*fomt)
	{
		switch(*fomt)
		{
		case 'c':
			putchar(va_arg(arg,char));//va_arg 获取参数列表中下一个未知参数,可以通过前面获取的字符判断下一个参数类型
			break;
		case 's':
			/*puts(va_arg(arg, char*));*/   //字符串可以直接用puts()函数输出
			ch = va_arg(arg, char*);//还可以定义一个指针变量接收获取的字符,从而用putchar()一个一个输出
			while (*ch)
			{
				putchar(*ch);
				ch++;
			}
				
				break;
		default :
			putchar(*fomt);

		}
		fomt++;
	
	}
	va_end(arg);//最后释放arg
}
int main()
{
	print("val:s ccccc\n","hello", 'w', 'o', 'r', 'l', 'd');
	system("pause");
	return 0;
}


<span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">在可变参数列表的访问过程中访问几个参数半途中止是可以的,但在一开始就想访问中间参数是做不到的。</span>

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