(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);
}
posted @ 2022-06-12 16:12  退後。  阅读(90)  评论(0编辑  收藏  举报