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

news2025/3/10 5:23:08

文章目录

  • 专栏导读
  • 不定参函数
  • C++风格不定参函数
  • 不定参宏函数

专栏导读

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

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

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

在这里插入图片描述

不定参函数

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

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

	return_type func_name (format_string, ...);
  • 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);
  • va_list:va_list是一个类型,用于声明一个参数列表的对象,它的本质其实是void*;
  • va_start:用于初始化va_list对象,使其指向不定参数列表的第一个参数;
  • va_arg:用于获取不定参数列表中的参数;
  • va_end:用于清空可变参数列表;

示例1

#include <stdio.h>
#include <stdarg.h>

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;
}

示例2

#define _GNU_SOURCE

#include <stdio.h>
#include <stdarg.h>

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;
}

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

函数原型如下:

#include <stdarg.h>
#include <stdio.h>

int vasprintf(char **str, const char *format, va_list ap);

C++风格不定参函数

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

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

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

示例3

#include <iostream>

// 无参特化
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;
}

不定参宏函数

示例4

#include <stdio.h>

#define LOG(format, ...) /
	printf("[%s : %d]\n", format, __FILE__, __LINE__, ##__VA_ARGS__)

int main()
{
    LOG("日志消息");
    return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007502.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据分析三剑客之Matplotlib

0.Matplotlib绘图和可视化 1.简介 我的前面两篇文章介绍了 Nimpy &#xff0c;Pandas 。今天来介绍一下Matplotlib。 简单来说&#xff0c;Matplotlib 是 Python 的一个绘图库。它包含了大量的工具&#xff0c;你可以使用这些工具创建各种图形&#xff0c;包括简单的散点图&…

Java多线程并发面试题

文章目录 Java并发基础并行和并发有什么区别&#xff1f;说说什么是进程和线程&#xff1f;Java线程创建方式&#xff1f;Runnable和Callable接口的区别&#xff1f;为什么调用start()方法时会执行run()方法&#xff0c;不直接调用run()方法&#xff1f;sleep()和wait()的区别&…

预约陪诊就诊小程序源码多城市开发版

陪诊小程序多城市版开发 小程序支持多城市开通&#xff0c;支持创建陪诊团队以及提成奖励设置&#xff0c;可以定义多种服务类型&#xff0c;订单流程简单明了&#xff0c;支持陪诊师手机端订单处理&#xff0c;家政类目可以轻松过审。 小程序市场前景&#xff1a; 人口老龄化…

强大:dynamsoft-barcode-reader-dotnet-9.6.30 Crack

dynamsoft-barcode-reader-dotnet 具有灵活 API 的强大条码扫描器 SDK 无论它是扭曲的、黑暗的、遥远的、模糊的、批量的还是移动的&#xff0c;我们都可以扫描它。速度快 条码扫描速度每分钟500 业界最快的扫描解码&#xff0c;可应用于不同场景&#xff1a; 多个条形码/二维…

【VS2022】调试

F9 创建或取消断点 ctrlF9 禁用断点 F5 开始调试&#xff08;到断点处停下来&#xff09; F10 逐过程&#xff08;不进入函数&#xff09; F11 逐语句 F5、F10、F11都可以直接进入调试 【调试】->【窗口】->【监视】&#xff0c;输入变量就可以观察到变量的值。 …

C语言数组和指针笔试题(二)(一定要看)

目录 字符数组二例题1例题2例题3例题4例题5例题6例题7总结 字符数组三例题1例题2例题3例题4例题5例题6例题7 字符数组二 char arr[] {a,b,c,d,e,f} 1:printf("%d\n", strlen(arr)); 2:printf("%d\n", strlen(arr0)); 3:printf("%d\n", strlen(…

Python小项目之Tkinter应用】随机点名/抽奖工具大优化:新增查看历史记录窗口!语音播报功能!修复预览文件按钮等之前版本的bug!

文章目录 前言一、实现思路二、关键代码查看历史记录按钮语音播报按钮三、完整代码总结前言 老生常谈,先看效果:(订阅专栏可获取完整代码) 初始状态下,我们为除了【设置】外的按钮添加弹窗,提示用户在使用工具之前要先【设置】。在设置界面,我们主要修改了【预览文件】…

每日一题 2596. 检查骑士巡视方案

难度&#xff1a;中等 很简单&#xff0c;从第 0 步开始模拟即可&#xff0c;唯一sb的就是测试用例中如果&#xff08;0&#xff0c;0&#xff09;处不为0的话就直接false&#xff0c;而不是去找0在哪 我的代码&#xff1a; class Solution:def checkValidGrid(self, grid: L…

2000-2021年上市公司全要素生产率数据OP法(含原始数据+计算代码+结果)

2000-2021年上市公司全要素生产率数据OP法&#xff08;含原始数据计算代码结果&#xff09; 1、时间&#xff1a;2000-2021年 2、指标&#xff1a;股票代码、年份、证券代码、固定资产净额、营业总收入、营业收入、营业成本、销售费用、管理费用、财务费用、支付给职工以及为…

防火墙 (五十四)

目录 前言 一、防火墙作用 二、防火墙分类 三、防火墙性能 四、硬件防火墙 五、软件防火墙 5.1 iptables 六、iptables应用 前言 本文就简单的介绍了防火墙的基础内容和一些简单案例的操作。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、防火墙…

jmeter线程组 bzm - Concurrency Thread Group 阶梯式压测

简介 bzm - Concurrency Thread Group 不是JMeter的官方插件&#xff0c;而是一种由Blazemeter提供的高级线程组插件&#xff0c;它提供了更灵活的并发性能测试设置。它可以在不同的时间内并发执行不同数量的线程&#xff0c;模拟不同的负载场景。 插件下载地址&#xff08;jme…

信创办公–基于WPS的EXCEL最佳实践系列 (通过函数实现灵活限制)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;通过函数实现灵活限制&#xff09; 目录 应用背景操作步骤1、sum函数的应用2、and函数的应用3、日期相关函数的应用4、eomonth函数的应用 应用背景 在Excel表格中&#xff0c;我们经常遇到需要大量计算或需要特殊处理的数据…

安达发|家具制造业APS高级计划与排程解决方案

在当今竞争激烈的市场环境下&#xff0c;家具制造业面临着诸多挑战&#xff0c;如原材料价格波动、人工成本上升、市场需求不确定性等。为了降低成本、提高生产效率和满足客户需求&#xff0c;家具制造企业需要寻求有效的计划与排程解决方案。本文将介绍一种基于先进生产计划系…

基于SSM的彩妆小样售卖商城

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Cpp/Qtday060913cpp基础

目录 将栈类实现成模板类 代码 效果 将队列类实现成模板类 代码 效果 思维导图 将栈类实现成模板类 代码 #include <iostream>using namespace std;template<typename T> class Stack { private:T data[128];int top; public:Stack();//Stack(T unit);~St…

比亚迪海洋家族再添新成员,合资车企又该绷不住了

燃油搅局者比亚迪最近又又又上新车啦&#xff0c;这次带来的是海洋家族中大型插电混动轿车—海豹 DM-i。 啥叫插电混动&#xff1f;简单来说同时搭载了汽油发动机、可外接电源充电的电池和电机&#xff1b; 有电时用电驱动电机做工&#xff0c;没电时用油驱动发动机做工&#…

pycharm虚拟环境安装指定python版本/ python3.8 / 从python3.9降级到3.8

我在网上找了一圈发现各种命令,尤其是说: virtualenv -p python3 py38 可以指定版本,我真的酸Q ! 这个命令是意思是创建一个 py38 目录,实际上用的版本还是环境变量所指向的版本. 1.下载 python 版本 要想指定版本,肯定是需要本机已经有一个版本,然后指定这个版本作为虚拟环…

⑥ 在vue中引入路由

什么是路由&#xff1a;管理页面的跳转&#xff08;vue-router&#xff09; 官方文档 https://router.vuejs.org/zh/introduction.html第一步&#xff1a;安装路由后启动项目 npm install --save vue-router配置独立的路由文件 在src目录文件下新建一个文件夹router&#xf…

C++--day6

将之前定义的栈类和队列类都实现成模板类 栈&#xff1a; #include <iostream>using namespace std; template<typename T> class zn { private:T *num;int top;int size; public: //有参构造函数 zn(int a):top(-1),size(a){numnew T[size]; } //析构函数 ~zn()…

通过 DevOps、CI/CD 和容器增强您的软件开发之旅...

软件行业已经在 DevOps、CI/CD 和容器中找到了针对开发导向问题的有效解决方案。尽管并不强制要求将这三者一起使用&#xff0c;但它们通常是相互补充和依赖的。 DevOps 促进开发和 IT 团队之间的协作&#xff0c;而 CI/CD 简化软件交付流程以更快地获得结果。容器化将应用程序…