• C++项目实战——基于多设计模式下的同步&异步日志系统-②-前置知识补充-不定参函数


    专栏导读

    🌸作者简介:花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。

    🌸专栏简介:本文收录于 C++项目——基于多设计模式下的同步与异步日志系统

    🌸相关专栏推荐:C语言初阶系列C语言进阶系列 C++系列数据结构与算法Linux

    在这里插入图片描述

    不定参函数

    C语言中的不定参数函数是一种特殊类型的函数,它允许你定义一个函数,可以接受不定数量的参数。这些函数通常用于处理不确定数量的输入,例如printfscanf等标准库函数,它们可以接受不同数量和类型的参数。

    不定参函数的声明格式如下:

    	return_type func_name (format_string, ...);
    
    • 1
    • return_type为函数返回值类型;
    • func_name为函数名;
    • format_string是一个格式化字符串,用于指定参数的数量和类型;
    • ... 表示不定数量的参数;

    在函数内部我们可以用一些宏或函数来对不定参数进行分解,常见的宏有va_startva_argva_end

        void va_start(va_list ap, last);
        type va_arg(va_list ap, type);
        void va_end(va_list ap);
    
    • 1
    • 2
    • 3
    • va_list:va_list是一个类型,用于声明一个参数列表的对象,它的本质其实是void*;
    • va_start:用于初始化va_list对象,使其指向不定参数列表的第一个参数;
    • va_arg:用于获取不定参数列表中的参数;
    • va_end:用于清空可变参数列表;

    示例1

    #include 
    #include 
    
    void printNum(int count, ...)
    {
        va_list ap;
        va_start(ap, count); // 初始化ap指针,使其指向不定参数列表的第一个参数
        for(int i = 0; i < count; i++)
        {
            int num = va_arg(ap, int); // 从不定参数列表中抽取int类型的参数
            printf("%d ", num);
        }
        printf("\n");
        va_end(ap); // 将ap置空
    }
    
    int main()
    {
        printNum(5, 1, 2, 3, 4, 5);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    示例2

    #define _GNU_SOURCE
    
    #include 
    #include 
    
    void myprintf(const char* format, ...)
    {
        va_list ap;
        va_start(ap, format);
        char* res;
        int ret = vasprintf(&res, format, ap);
        if(ret != -1)
        {
            printf(res);
            free(res); // res指向动态开辟的空间,需要手动释放
        }
        va_end(ap);
    }
    int main()
    {
        myprintf("%s-%d\n", "huaxiangyun", 100);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注意
    示例中vasprintf 是一个 C 库函数,它可以通过可变参数创建一个格式化的字符串,并将其存储在动态分配的内存中。它的使用方法与 printf类似,但它不会将结果打印到标准输出流中,而是将其存储在一个指向字符数组的指针中

    函数原型如下:

    #include 
    #include 
    
    int vasprintf(char **str, const char *format, va_list ap);
    
    • 1
    • 2
    • 3
    • 4

    C++风格不定参函数

    在C++中,有两种主要方式来创建不定参数函数:

    • C风格的不定参数函数:这种方式与C语言中的不定参数函数类似,使用了C标准库中的va_list、va_start、va_arg和va_end宏。这种方式在C++中仍然有效,但不够类型安全,不太推荐在现代C++代码中使用。

    • C++11引入的可变参数模板:这是更现代和类型安全的方式,使用了C++的模板和新的语法特性。可变参数模板允许你定义一个接受不定数量参数的函数,并且能够在编译时进行类型检查。这种方式更灵活,并且是C++推荐的方式。

    示例3

    #include 
    
    // 无参特化
    void xprintf()
    {
        std::cout << std::endl;
    }
    
    template <typename T, typename ...Args>
    void xprintf(const T &v, Args &&...args)
    {
        std::cout << v;
        if((sizeof ...(args)) > 0)
        {
            xprintf(std::forward<Args>(args)...); // 递归分解参数包
        }
        else
        {
            xprintf();
        }
    }
    
    int main()
    {
        xprintf("huaxinagyun");
        xprintf("aaaa", 1000);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    不定参宏函数

    示例4

    #include 
    
    #define LOG(format, ...) /
    	printf("[%s : %d]\n", format, __FILE__, __LINE__, ##__VA_ARGS__)
    
    int main()
    {
        LOG("日志消息");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

  • 相关阅读:
    dff寄存器setup hold演示
    【数据结构】F:B DS图_课程表 拓扑排序实现
    JAVA计算机毕业设计重工教师职称管理系统Mybatis+源码+数据库+lw文档+系统+调试部署
    机器人操控电脑,华为天才少年稚晖君再出手,直呼:项目不太难
    UE5 C++ 使用TimeLine时间轴实现开关门
    【DBA100人】胡中豪:国产分布式数据库DBA炼成记
    【小程序】HbuilderX搭建开发环境
    深拷贝和浅拷贝是什么,有什么区别?
    使用React、Express实现一个问卷发布/收集系统
    Redis本地远程(外部)连接失败详解
  • 原文地址:https://blog.csdn.net/gllll_yu/article/details/132735992