C/C++可变参数列表
可变参数列表
- 可变参数宏--__VA_ARGS__
- C风格不定参使用
- 补充知识:函数调用时参数的压栈顺序及内存使用
- 使用不定参模拟实现printf
- C++风格不定参数的使用
可变参数宏–VA_ARGS
#include <stdio.h>//...表示不定参,__VA_ARGS__使用不定参
// __FILE__ 文件名
//__LINE__ 行号
//__VA_ARGS__ 用于在宏替换部分中,表示可变参数列表;
//当可变参数的个数为0时,##起到把前面多余的","去掉的作用,否则会编译出错
#define LOG(fmt,...) printf("[%s:%d]" fmt,__FILE__,__LINE__,##__VA_ARGS__);int main()
{LOG("可变参数列表");//最终展开的代码相当于printf("[%s:%d]" "可变参数列表",__FILE__,__LINE__)//如果不加##,会报错//printf("%d""nihao",6);可以编译通过return 0;
}
在这里我之前一直有一个误区:
1.我认为printf("%d""nihao",6);是不合法的,因为格式化参数后面没有加,,直到今天认识了可变参数宏,才认识到
2."%d""nihao"会自动连接
C风格不定参使用
使用之前需要自己定义一个va_list 变量
va_start()函数 语法
void va_start(va_list ap,param);
参数ap为参数自身;
参数param为第一个参数。
va_arg()函数用于调用可变参数列表
type va_arg(va_list ap,type);
参数ap为可变参数自身;参数type为要获取的参数的指定类型,返回这个指定类型的值,并把ap的位置指向变参表的下一个变量位置
va_end()函数用于停止使用可变参数。
void va_end(va_list ap);
参数ap为参数自身。
简单使用
void print(int cnt,...)
{va_list ap;va_start(ap,cnt);//获取cnt参数之后的第一个参数的地址即第一个不定参地址for(int i=0;i<cnt;++i){int num=va_arg(ap,int);//获取不定参printf("param[%d]:%d\n",i,num);}va_end(ap);//使用完将ap指针置空}
补充知识:函数调用时参数的压栈顺序及内存使用
以printf(const char* format,…)为例
- printf函数是一个不定参函数。
- 编译器通过format的%占位符的个数来获取参数的个数。
- 假设函数压栈顺序是从左至右,format先入栈,各个参数再入栈,最后pc入栈入栈完之后,想知道参数的个数就要读取format,但要读取format就得知道参数的个数,陷入了一个死循环。
- 如果函数压栈顺序是从右至左,未知个数的参数先入栈,format再入栈,最后压pc入栈。这时候要想知道参数的个数只需要将栈顶指针加2即可读取到format。
- 函数调用栈从高往低使用
使用不定参模拟实现printf
int vasprintf(char **strp, const char *fmt, va_list ap);
vasprintf 是一个 C 库函数,它可以通过可变参数创建一个格式化的字符串,并将其存储在动态分配的内存中。它的使用方法与 printf 类似,但它不会将结果打印到标准输出流中,而是将其存储在一个指向字符数组的指针中
void MyPrint(const char *fmt, ...)
{va_list ap;va_start(ap,fmt);char* res;int ret=vasprintf(&res,fmt,ap);if(ret !=-1){printf(res);free(res);}va_end(ap);}
C++风格不定参数的使用
需要借助C++11内的万能引用与完美转发及可变参数模版包
#include <iostream>
#include <cstdarg>
#include <memory>
#include <functional>//特化
void CgagaPrint()
{std::cout<<std::endl;
}template<class T,class ...Args>
void CgagaPrint(const T& v,Args&& ...args)
{std::cout<<v;if((sizeof ...(args))>0){//完美转发CgagaPrint(std::forward<Args>(args)...);}else{CgagaPrint();}
}int main()
{CgagaPrint("nihao",6,5,4);
}
相关文章:
C/C++可变参数列表
可变参数列表 可变参数宏--__VA_ARGS__C风格不定参使用补充知识:函数调用时参数的压栈顺序及内存使用使用不定参模拟实现printf C风格不定参数的使用 可变参数宏–VA_ARGS #include <stdio.h>//...表示不定参,__VA_ARGS__使用不定参 // __FILE__ …...
MongoDB基本命令使用
成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作。 输入help可以看到基本操作命令: show dbs:显示数据库列表 show collections:显示当前数据库中的集合(类似关系数据库中的表…...
uniapp 微信小程序 上下滚动的公告通知(只取前3条)
效果图: <template><view class"notice" click"policyInformation"><view class"notice-icon"><image mode"aspectFit" class"img" src"/static/img/megaphone.png"></i…...
OSPF在MGRE上的实验
实验题目如下: 实验拓扑如下: 实验要求如下: 【1】R6为ISP只能配置ip地址,R1-5的环回为私有网段 【2】R1/4/5为全连的MGRE结构,R1/2/3为星型的拓扑结构,R1为中心站点 【3】所有私有网段可以互相通讯&…...
什么样的跨网文件安全交换系统 可实现安全便捷的文件摆渡?
进入互联网时代,网络的运算和数据管理能力助力各个行业高速发展,但同样带来了一些网络安全隐患,网络攻击、数据窃取、敏感信息泄露等问题。为此,我国出台了系列政策来全面提升银各行业系统网络安全整体防护水平,其中“…...
C语言memset函数的作用
memset函数是C语言中的一个库函数,其作用是将一块内存区域的每个字节都设置为指定的值。 memset函数的原型如下: void *memset(void *ptr, int value, size_t num); 参数解释: ptr:指向要填充的内存区域的指针。value࿱…...
暑假刷题第23天--8/7
D-游游的k-好数组_牛客周赛 Round 6 (nowcoder.com)(关键--a[1]a[k1]) #include<iostream> #include<algorithm> using namespace std; const int N100005; int a[N]; typedef pair<int,int>PII; PII b[N]; void solve(){int n,k,x;…...
Double DQN缓解动作价值的高估问题
1、算法: Selection using DQN: a ⋆ argmax a Q ( s t 1 , a ; w ) . a^{\star}\operatorname*{argmax}_{a}Q(s_{t1},a;\mathbf{w}). a⋆aargmaxQ(st1,a;w). Evaluation using target network: y t r t γ ⋅ Q ( s t 1 , a ⋆ ; w − )…...
【C#学习笔记】内存管理
文章目录 分配内存释放内存GC标记清除算法分代算法大对象和小对象 .NET的GC机制有这样两个问题: 官方文档 自动内存管理 自动内存管理是CLR在托管执行过程中提供的服务之一。 公共语言运行时的垃圾回收器为应用程序管理内存的分配和释放。 对开发人员而言…...
面试之快速学习c++11- 列表初始化和 lambda匿名函数的定义
学习地址: http://c.biancheng.net/view/3730.html 8. C11列表初始化(统一了初始化方式) 我们知道,在 C98/03 中的对象初始化方法有很多种,请看下面的代码: //初始化列表 int i_arr[3] { 1, 2, 3 }; /…...
CI/CD—Docker初入门学习
1 docker 了解 1 Docker 简介 Docker 是基于 Go 语言的开源应用容器虚拟化技术。Docker的主要目标是build、ship and run any app,anywhere,即通过对应用组件的封装、分发、部署、运行等生命周期的管理,达到应用组件级别的一次封装、到处运…...
多线程的创建,复习匿名内部类,Thread的一些方法,以及lambda的变量捕捉,join用法
一、💛 Java的Thread类表示线程 1.创建类,继承Thread重写run方法 2.创建类,实现Runnable重写run方法 3.可以继承Thread重写run基于匿名内部类 4.实现Runnable重写run基于匿名内部类 5.lamdba表达式表示run方法的内容(推荐&#x…...
瑞吉外卖系统05
哈喽!大家好,我是旷世奇才李先生 文章持续更新,可以微信搜索【小奇JAVA面试】第一时间阅读,回复【资料】更有我为大家准备的福利哟,回复【项目】获取我为大家准备的项目 最近打算把我手里之前做的项目分享给大家&#…...
D455+VINS-Fusion+surfelmapping 稠密建图(三)
继续,由surfelmapping建立的点云生成octomap八叉树栅格地图 一、安装OctomapServer 建图包 安装插件 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-…...
rv1109/1126 rknn 模型部署过程
rv1109/1126是瑞芯微出的嵌入式AI芯片,带有npu, 可以用于嵌入式人工智能应用。算法工程师训练出的算法要部署到芯片上,需要经过模型转换和量化,下面记录一下整个过程。 量化环境 模型量化需要安装rk的工具包: rockchip-linux/rk…...
Android平台一对一音视频通话方案对比:WebRTC VS RTMP VS RTSP
一对一音视频通话使用场景 一对一音视频通话都需要稳定、清晰和流畅,以确保良好的用户体验,常用的使用场景如下: 社交应用:社交应用是一种常见的使用场景,用户可以通过音视频通话进行面对面的交流;在线教…...
--binlog-row-event-max-size
--binlog-row-event-max-size MySQL中用于控制rows格式的Binlog,binlog以chunk的方式存储,每个chunk的大小由binlog-row-event-max-size 进行控制; 如果event比较大的时候可以调大这个值;;改值必须是256的倍数&#…...
Jmeter命令行运行实例讲解
1. 简介 使用非 GUI 模式,即命令行模式运行 JMeter 测试脚本能够大大缩减所需要的系统资 本文介绍windows下以命令行模式运行的方法。 1.1. 命令介绍 jmeter -n -t <testplan filename> -l <listener filename> 示例: jmeter -n -t test…...
pl/sql函数如何返回多行数据?在线等......
编辑csm8109022010-01-27 09:59:18 这个问题我以前问过类似的,但一直没得到如意的答案!在oracle 里soctt的用户下的emp表,比如写一个函数,传入的参数为部门编号,然后返回所有该部门人员信息的函数。要用到游标&…...
Ubuntu Find命令详解
一、Find命令简介 Ubuntu的Find命令是一种常用的终端指令,用于在文件系统中查找符合条件的文件和目录。该命令的语法格式如下: find [PATH] [OPTION] [EXPRESSION]其中,PATH表示待查找的目录,OPTION为选项参数,EXPRES…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
