C/C++ #运算符、##运算符、变参宏 ...和_ _VA_ARGS_ _
文章目录
- 用宏参数创建字符串:#运算符
- 函数宏
- #号作为一个预处理运算符,可以把记号转换成字符串
- 预处理器粘合剂:##运算符
- 变参宏:...和_ _VA_ARGS_ _
- 参考
用宏参数创建字符串:#运算符
函数宏
下面是一个类函数宏:
#define PSQR(X) printf("The square of X is %d.\n", ((X)*(X)));
假设这样使用宏:
PSQR(8);
输出为:
The square of X is 64.
注意双引号字符串中的X被视为普通文本,而不是一个可被替换的记号。
#号作为一个预处理运算符,可以把记号转换成字符串
C允许在字符串中包含宏参数。
在类函数宏的替换体中,#号作为一个预处理运算符,可以把记号转换成字符串。
例如,如果x是一个宏形参,那么#x就是转换为字符串"x"的形参名。这个过程称为字符串化(stringizing)。
/* subst.c -- 在字符串中替换 */
#include <stdio.h>
#define PSQR(x) printf("The square of " #x " is %d.\n",((x)*(x)))
int main(void)
{int y = 5;PSQR(y);PSQR(2 + 4);return 0;
}
该程序的输出如下:
The square of y is 25.
The square of 2 + 4 is 36.
调用第1个宏时,用"y"替换#x。
调用第2个宏时,用"2 + 4"替换#x。
预处理器粘合剂:##运算符
与#运算符类似,##运算符可用于类函数宏的替换部分。
而且,##还可用于对象宏的替换部分。
##运算符把两个记号组合成一个记号。
例如,可以这样做:
#define XNAME(n) x ## n
然后,宏
XNAME(4)
将展开为
x4。
程序演示了##作为记号粘合剂的用法。
// glue.c -- 使用##运算符
#include <stdio.h>
#define XNAME(n) x ## n
#define PRINT_XN(n) printf("x" #n " = %d\n", x ## n);
int main(void)
{int XNAME(1) = 14; // 变成 int x1 = 14;int XNAME(2) = 20; // 变成 int x2 = 20;int x3 = 30;PRINT_XN(1); // 变成 printf("x1 = %d\n", x1);PRINT_XN(2); // 变成 printf("x2 = %d\n", x2);PRINT_XN(3); // 变成 printf("x3 = %d\n", x3);return 0;
}
该程序的输出如下:
x1 = 14
x2 = 20
x3 = 30
注意,PRINT_XN()宏用#运算符组合字符串,##运算符把记号组合为一
个新的标识符。
变参宏:…和_ VA_ARGS _
一些函数(如 printf())接受数量可变的参数。
C99/C11也对宏提供了这样的工具。虽然标准中未使用“可变”(variadic)这个词,但是它已
成为描述这种工具的通用词(虽然,C标准的索引添加了字符串化(stringizing)词条,但是,标准并未把固定参数的函数或宏称为固定函数和不变宏)。
通过把宏参数列表中最后的参数写成省略号(即,3个点…)来实现这一功能。这样,预定义宏_ VA_ARGS _可用在替换部分中,表明省略号代表什么。例如,下面的定义:
#define PR(...) printf(_ _VA_ARGS_ _)
假设稍后调用该宏:
PR("Howdy");
PR("weight = %d, shipping = $%.2f\n", wt, sp);
对于第1次调用,_ _VA_ARGS_ _展开为1个参数:"Howdy"
对于第2次调用,_ _VA_ARGS_ _展开为3个参数:"weight = %d,shipping = $%.2f\n"、wt、sp。
因此,展开后的代码是:
printf("Howdy");
printf("weight = %d, shipping = $%.2f\n", wt, sp);
程序演示了一个示例,该程序使用了字符串的串联功能和#运算符。
// variadic.c -- 变参宏
#include <stdio.h>
#include <math.h>
#define PR(X, ...) printf("Message " #X ": " __VA_ARGS__)
int main(void)
{double x = 48;double y;y = sqrt(x);PR(1, "x = %g\n", x);PR(2, "x = %.2f, y = %.4f\n", x, y);return 0;
}
第1个宏调用,X的值是1,所以#X变成"1"。
展开后成为:
print("Message " "1" ": " "x = %g\n", x);
然后,串联4个字符,把调用简化为:
print("Message 1: x = %g\n", x);
下面是该程序的输出:
Message 1: x = 48
Message 2: x = 48.00, y = 6.9282
记住,省略号只能代替最后的宏参数:
#define WRONG(X, ..., Y) #X #_ _VA_ARGS_ _ #y //不能这样做
参考
《C Primer Plus》
相关文章:
C/C++ #运算符、##运算符、变参宏 ...和_ _VA_ARGS_ _
文章目录 用宏参数创建字符串:#运算符函数宏#号作为一个预处理运算符,可以把记号转换成字符串 预处理器粘合剂:##运算符变参宏:...和_ _VA_ARGS_ _参考 用宏参数创建字符串:#运算符 函数宏 下面是一个类函数宏&#…...
【全网首发】【Python】Python控制parrot ARDrone 2.0无人机
🎉欢迎来到Python专栏~Python控制parrot ARDrone 2.0无人机 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒🍹 ✨博客主页:小夏与酒的博客 🎈该系列文章专栏:Python学习专栏 文章作者技术和水平有限,如果文中出现错误…...
DPU国产生态版图又双叒扩大了
DPU朋友圈迎来30新伙伴!近期,中科驭数已与联想、中科可控、统信、欧拉、龙蜥社区、新支点、亚信科技、人大金仓、瀚高、南大通用、GreatSQL、阿里云、曙光云等超30家关键厂商完成兼容性互认证。测试报告显示,中科驭数DPU系列产品在产品兼容性…...
YOLOv5算法进阶改进(3)— 引入深度可分离卷积C3模块 | 轻量化网络
前言:Hello大家好,我是小哥谈。深度可分离卷积是一种卷积神经网络中的卷积操作,它可以将标准卷积分解为两个较小的卷积操作:深度卷积和逐点卷积。深度卷积是在每个输入通道上分别执行卷积,而逐点卷积是在所有通道上执行卷积。这种分解可以大大减少计算量和参数数量,从而提…...
Linux的root用户
拥有最大权限的用户名为root su和exit命令 su命令就是用于账户切换的系统命令Switch user 语法:su - [用户名] -符号可选,表示是否在切换用户后加载环境变量,建议带上 参数:用户名,表示要切换的用户,用…...
linux环境安装SVN,以及常用的SVN操作
1、检查系统是否已经安装如果安装就卸载 检查: svnserve --version 卸载: yum remove subversion 2、安装 yum install subversion 3、建立SVN库(文件位置可自由) 创建仓库文件夹: mkdir -p /opt/svn/repositor…...
30天精通Nodejs--第十天:OS
目录 引言OS 模块简介核心概念基本用法获取 CPU 架构获取内存信息获取系统平台高级特性CPUS网络接口引言 os 模块是一个非常重要的组成部分,它提供了一系列用于获取和处理操作系统信息的工具函数,使得我们能够在 Node.js环境中获取有关系统的各种信息。在本文中,将深入介绍…...
C#使用时序数据库 InfluxDB
一、安装 https://docs.influxdata.com/influxdb/v2/install/?tWindows 解压后使用cmd运行 访问 localhost:8086 配置 第一次登入会初始化 配置登入账号 保存TOKEN 这个TOKEN用于后期代码链接访问数据库,忘记了只能删除重新生成 点击QUCK START进入管理页面 …...
正则表达式:验证中英文长度限制16个字符(8个中文),支持中文字母数字或者下划线
1.中文字母数字或者下划线 2.长度限制16个字符(8个中文) html: <input class"form-control text" maxlength"17" name"name" placeholder"输入16个字符以内的备注名称" type"text" v-model.trim"remarkName" …...
kafka和rocketMq的区别
kafka topic 中每一个分区会有 Leader 与 Follow。Kafka 的内部机制可以保证 topic 某一个分区的 Leader 与 Follow 不在同一台机器上 Leader 节点承担一个分区的读写,Follow 节点只负责数据备份 如果 Leader 分区所在的 Broker 节点宕机,会触发主从节…...
Git推送本地代码到远程仓库
Git推送本地代码到远程仓库 1、首先需要安装Git,如果已经安装,请跳过。下载地址:https://git-for-windows.github.io/ 2、安装好git服务器后。首先找到你项目的文件夹,比如项目名称为Item,进入到这个文件夹࿰…...
OncePerRequestFilter详解
OncePerRequestFilter是什么 OncePerRequestFilter是Spring框架提供的一个过滤器,确保在一次HTTP请求期间只执行一次特定的过滤器逻辑。它继承了GenericFilterBean类,并实现了javax.servlet.Filter接口。在Spring框架中,过滤器是一种拦截器&…...
Accelerate 0.24.0文档 二:DeepSpeed集成
文章目录 一、 DeepSpeed简介二、DeepSpeed集成(Accelerate 0.24.0)2.1 DeepSpeed安装2.2 Accelerate DeepSpeed Plugin2.2.1 ZeRO Stage-22.2.2 ZeRO Stage-3 with CPU Offload2.2.3 accelerate launch参数 2.3 DeepSpeed Config File2.3.1 ZeRO Stage-…...
【系统架构设计】架构核心知识: 2.3 UML图
目录 一 UML 1 用例图 2 类图/对象图关系 3 活动图 4 顺序图 5 通信图...
2023年09月青少年软件编程(C语言)等级考试试卷(三级)
青少年软件编程(C语言)等级考试试卷(三级) 谁是你的潜在朋友 “臭味相投”——这是我们描述朋友时喜欢用的词汇。两个人是朋友通常意味着他们存在着许多共同的兴趣。然而作为一个宅男,你发现自己与他人相互了解的机会…...
SQLite3 数据库学习(一):数据库和 SQLite 基础
参考引用 SQL 必知必会SQLite 权威指南(第二版)关系型数据库概述 1. 数据库基础 1.1 什么是数据库 数据库(database):保存有组织的数据的容器(通常是一个文件或一组文件) 可以将其想象为一个文…...
上机4KNN实验4
目录 编程实现 kNN 算法。一、步骤二、实现代码三、总结知识1、切片2、iloc方法3、归一化4、MinMaxScale()5、划分测试集、训练集6、KNN算法 .py 编程实现 kNN 算法。 1、读取excel表格存放的Iris数据集。该数据集有5列,其中前4列是条件属性…...
产品经理如何保持核心竞争力?学会这些方法
如今,内卷的风已经吹到各行各业,产品经理也不例外。想要在内卷日益严重的环境中生存下来,产品经理就需要学会保持自己的核心竞争力。那么,产品经理要如何才能在内卷时代持续保持自己的核心竞争力呢? 1、建立快速学习的…...
终知人生苦短,何必自我为难
不是少年比他当年的那个目标更强,也不是他完全丧失了冲关过坎的勇气,而是他知道了自己能力的边界和极限,迫切需要外界的帮助。 不再自我设限,不再自我挑战,而是想用最简便、最快捷、最省精力的路径,解决掉困…...
C++阶段复习‘‘‘‘总结?【4w字。。。】
文章目录 前言类和对象C类定义和对象定义类成员函数C 类访问修饰符公有(public)成员私有(private)成员受保护(protected)成员 继承中的特点类的构造函数和析构函数 友元函数内联函数this指针指向类的指针类…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
Razor编程中@Html的方法使用大全
文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...
【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
