『 C 』 `##` 在 C 语言宏定义中的作用解析
文章目录
- `##` 运算符的基本概念
- 可变参数宏与 `##` 的应用
- 可变参数宏简介
- `##` 处理可变参数的两种情况
- 可变参数列表为空
- 可变参数列表不为空
- 示例代码验证
在 C 和 C++ 编程里,宏定义是个很有用的工具。今天咱们就来聊聊 ## 这个预处理器连接运算符在宏定义中的作用,特别是在可变参数宏里的应用。
## 运算符的基本概念
## 是预处理器的连接运算符,也叫“令牌粘贴”运算符。它能把两个预处理令牌连在一起,变成一个新的预处理令牌。在宏定义里,它主要用于处理可变参数。这部分内容在 C 语言标准文档里有明确说明,它是 C99 及以后标准支持的特性。
可变参数宏与 ## 的应用
可变参数宏简介
C99 引入了可变参数宏的概念。在宏定义里,... 表示可变参数部分,__VA_ARGS__ 会被替换成实际传递的可变参数列表。比如下面这个 LOG 宏:
#define LOG(level, format, ...) { \if (level >= LDEFAULT) { \time_t t = time(NULL);\ struct tm *lt = localtime(&t);\ char time_tmp[32] = {0}; \strftime(time_tmp, 31, "%m-%d %T", lt);\ fprintf(stdout, "[%s][%s:%d] " format "\n", time_tmp, __FILE__, __LINE__, ##__VA_ARGS__); \} \
}
## 处理可变参数的两种情况
可变参数列表为空
当调用 LOG 宏时没传递可变参数,像 LOG(LINF, "No variable arguments");,## 能消除 __VA_ARGS__ 前面的逗号。要是没有 ##,宏展开后会有多余逗号,导致编译出错。有了 ##,可变参数为空时逗号会被移除,保证代码正确。
可变参数列表不为空
如果传递了可变参数,比如 LOG(LINF, "The sum is %d", a + b);,##__VA_ARGS__ 会被替换成实际的可变参数 a + b,宏展开后就能正确把参数传给 fprintf 函数。
示例代码验证
下面是个简单示例,展示 LOG 宏的使用和 ## 的作用:
#include <stdio.h>
#include <time.h>#define LDBG 0
#define LINF 1
#define LERR 2
#define LDEFAULT LINF#define LOG(level, format, ...) { \if (level >= LDEFAULT) { \time_t t = time(NULL);\ struct tm *lt = localtime(&t); \char time_tmp[32] = {0}; \strftime(time_tmp, 31, "%m-%d %T", lt);\ fprintf(stdout, "[%s][%s:%d] " format "\n", time_tmp, __FILE__, __LINE__, ##__VA_ARGS__); \} \
}int main() {int a = 10, b = 20;LOG(LINF, "Starting the program");LOG(LINF, "The sum of %d and %d is %d", a, b, a + b);return 0;
}
在这个示例中,第一个 LOG 调用没传可变参数,第二个传了。因为用了 ##,两种情况都能正确编译运行。
通过以上分析,我们能清楚看到 ## 运算符在处理可变参数宏时的重要性,它保证了代码的灵活性和正确性。希望大家在编程中能灵活运用这个特性。
相关文章:
『 C 』 `##` 在 C 语言宏定义中的作用解析
文章目录 ## 运算符的基本概念可变参数宏与 ## 的应用可变参数宏简介## 处理可变参数的两种情况可变参数列表为空可变参数列表不为空 示例代码验证 在 C 和 C 编程里,宏定义是个很有用的工具。今天咱们就来聊聊 ## 这个预处理器连接运算符在宏定义中的作用ÿ…...
独立成分分析 (ICA):用于信号分离或降维
人工智能例子汇总:AI常见的算法和例子-CSDN博客 独立成分分析 (Independent Component Analysis, ICA) 是一种用于信号分离和降维的统计方法,常用于盲源分离 (Blind Source Separation, BSS) 问题,例如音频信号分离或脑电信号 (EEG) 处理。…...
为什么会有函数调用参数带标签的写法?Swift函数调用的参数传递需要加前缀是否是冗余?函数调用?函数参数?
为什么会有函数调用参数带标签的写法? ObjC函数参数形式与众不同,实参前会加前缀,尤其参数很多的情况,可读性很强。例如: [person setAge: 29 setSex:1 setClass: 35]; 这种参数前面加前缀描述也被叫标签(Label). 注意࿰…...
实际操作 检测缺陷刀片
号he 找到目标图像的缺陷位置,首先思路为对图像进行预处理,灰度-二值化-针对图像进行轮廓分析 //定义结构元素 Mat se getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1)); morphologyEx(thre, tc, MORPH_OPEN, se, Point(-1, -1), 1); …...
使用Pygame制作“青蛙过河”游戏
本篇博客将演示如何使用 Python Pygame 从零开始编写一款 Frogger 风格的小游戏。Frogger 是一款早期街机经典,玩家需要帮助青蛙穿越车水马龙的马路到达对岸。本示例提供了一个精简原型,包含角色移动、汽车生成与移动、碰撞检测、胜利条件等关键点。希望…...
BUU17 [RoarCTF 2019]Easy Calc1
自用 源代码 $(#calc).submit(function(){$.ajax({url:"calc.php?num"encodeURIComponent($("#content").val()),type:GET,success:function(data){$("#result").html(<div class"alert alert-success"><strong>答案:&l…...
堆的实现——对的应用(堆排序)
文章目录 1.堆的实现2.堆的应用--堆排序 大家在学堆的时候,需要有二叉树的基础知识,大家可以看我的二叉树文章:二叉树 1.堆的实现 如果有⼀个关键码的集合 K {k0 , k1 , k2 , …,kn−1 } ,把它的所有元素按完全⼆叉树…...
新生讲课——图和并查集
1.图的存储 (1).邻接矩阵 邻接矩阵可以借助stl中的vector,我们通过开一个二维矩阵,g[u]中存储的是u可以到达的点,定义如下 const int N 2e5 10; vector<int> g[N] 若是遇到带权图则定义如下 const int N 2e5 10; vector <pair <int ,…...
基于深度学习的视觉检测小项目(十七) 用户管理后台的编程
完成了用户管理功能的阶段。下一阶段进入AI功能相关。所有的资源见文章链接。 补充完后台代码的用户管理界面代码: import sqlite3from PySide6.QtCore import Slot from PySide6.QtWidgets import QDialog, QMessageBoxfrom . import user_manage # 导入使用ui…...
实战:利用百度站长平台加速网站收录
本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/33.html 利用百度站长平台加速网站收录是一个实战性很强的过程,以下是一些具体的步骤和策略: 一、了解百度站长平台 百度站长平台是百度为网站管理员提供的一系列工…...
web-XSS-CTFHub
前言 在众多的CTF平台当中,作者认为CTFHub对于初学者来说,是入门平台的不二之选。CTFHub通过自己独特的技能树模块,可以帮助初学者来快速入门。具体请看官方介绍:CTFHub。 作者更新了CTFHub系列,希望小伙伴们多多支持…...
【C++】P1957 口算练习题
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目描述输入格式:输出格式: 💯我的做法代码实现: 💯老师的做法代码实现: 💯对比分析&am…...
第二十三章 MySQL锁之表锁
目录 一、概述 二、语法 三、特点 一、概述 表级锁,每次操作锁住整张表。锁定粒度大,发生锁冲突的概率最高,并发度最低。应用在MyISAM、InnoDB、BDB等存储引擎中。 对于表级锁,主要分为以下三类: 1. 表锁 2. 元数…...
linux 进程补充
环境变量 基本概念 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如:我们在编写C/C代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪 里,但是照样可以链接成功&#…...
渗透测试之文件包含漏洞 超详细的文件包含漏洞文章
目录 说明 通常分为两种类型: 本地文件包含 典型的攻击方式1: 影响: 典型的攻击方式2: 包含路径解释: 日志包含漏洞: 操作原理 包含漏洞读取文件 文件包含漏洞远程代码执行漏洞: 远程文件包含…...
Java 大视界 -- Java 大数据在智能医疗影像诊断中的应用(72)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也期待你毫无保留地分享独特见解,愿我们于此携手成长,共赴新程!💖 一、…...
Web - CSS3浮动定位与背景样式
概述 这篇文章主要介绍了 CSS3 中的浮动定位、背景样式、变形效果等内容。包括 BFC 规范与创建方法、浮动的功能与使用要点、定位的多种方式及特点、边框与圆角的设置、背景的颜色、图片等属性、多种变形效果及 3D 旋转等,还提到了浏览器私有前缀。 BFC规范与浏览…...
ConcurrentHashMap线程安全:分段锁 到 synchronized + CAS
专栏系列文章地址:https://blog.csdn.net/qq_26437925/article/details/145290162 本文目标: 理解ConcurrentHashMap为什么线程安全;ConcurrentHashMap的具体细节还需要进一步研究 目录 ConcurrentHashMap介绍JDK7的分段锁实现JDK8的synchr…...
系统学习算法:专题九 穷举vs暴搜vs深搜vs回溯vs剪枝
其中标题的深搜,回溯,剪枝我们之前专题都已经有过学习和了解,这里多了两个穷举和暴搜,其实意思都差不多,穷举就是穷尽力气将所有情况都列举出来,暴搜就是暴力地去一个一个情况搜索,所以就是全部…...
解决 Pandas DataFrame 索引错误:KeyError:0
在使用 Pandas 处理数据时,KeyError 是一个常见的问题,尤其是在尝试通过索引访问数据时。本文将通过一个实际案例(使用SKLearn中的MINIST数据集为例),详细分析 KeyError 的原因,并提供解决方法。 1 问题背…...
React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
UE5 音效系统
一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类,将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix,将上述三个类翻入其中,通过它管理每个音乐…...
