(C/C++ 学习) 41. C 语言可变长参数
作者:互联网
前言:本文记录自己学习 C 语言可变长参数的设计原理,供自己以后复习,读者基本知识自行百度(涉及到参数压栈的相关知识)。C 语言提供了几个宏函数为实现变长参数提供了接口。
1. 头文件 : #include <stdarg.h>
2. 宏函数(右边注释部分为宏函数的模拟实现) :
Example : // void myPrintf(char* arg1, ...);
va_list ap; // char *ap; va_start(ap,arg1); // ap = (char *)&arg1 + sizeof(arg1); va_arg(ap, T); // *(T*) [ (ap = ap + sizeof(T)) - sizeof(T) ]; va_end(ap); // ap = (char *)0;
注意 1: 在 C 语言中为了实现一个变长参数的函数,必须要提供函数的第一个参数,用于获取该函数中整个参数栈的起始地址。上述宏函数中 arg1 即为可变长参数函数的第一个参数。
注意 2:va_arg(ap, T) 用于从参数列表中获取一个类型为 T 的参数,这个操作会更新 ap 指针,因此,va_arg() 只能按顺序获取变长参数函数的每一个参数。
注意 3:根据 C 标准,对于不确定参数的函数,传入参数会默认进行自动参数类型提升, 例如:传入 char 会被转成 int,float 会被转成 double,因此 va_arg(ap, char) 这种写法是不对的,因为可变长参数函数根本不会有 char 类型的参数。对于这部分,自行去查资料了解具体的提升规则。
3. 利用变长参数设计模拟实现 printf() 函数部分功能 :
void my_printf(const char* fmt, ... ) { va_list ap; va_start(ap,fmt); for (; *fmt; ++fmt) { if (*fmt != '%') { // 普通字符原样输出 putchar(*fmt); continue; } fmt++;switch (*fmt) { case '%': putchar('%'); break; // 输出 % case 'd': cout << va_arg(ap, int); break; // 输出 整型变量 case 'c': putchar(va_arg(ap, int)); break; // 输出 字符 case 's': cout << va_arg(ap, char*); break; // 输出 字符串 } } va_end(ap); }
标签:va,函数,fmt,C++,41,char,ap,参数,可变 来源: https://www.cnblogs.com/tuihou/p/16368196.html