当前位置: 首页 > news >正文

C语言大佬的必杀技---宏的高级用法

C语言大佬的必杀技—宏的高级用法

目录:
  • 字符串化
  • 标记的拼接
  • 宏的嵌套
  • 替换多条语句
  • 防止一个文件被重复包含
  • 宏和函数的区别

可能大家在学习的时候用得比较少,但是在一些代码量比较大的时候,这样使用,可以大大的提高代码的可读性,方便我们后期维护

1、字符串化 -------( 打印变量的值和格式化字符串 ):
#define test(x,format) printf(#x "= %" #format "\n", x)

说明 :

  1. #x 在宏定义中被称为字符串化操作符,它将 x 参数转换为一个字符串,并在代码中插入。
  2. "= %" 是一个字符串,用于指定输出的格式。
  3. #format 也是字符串化操作符,将 format 参数转换为一个字符串,并在代码中插入。
  4. 整个宏的作用就是 : 可以用于打印变量的值和格式化字符串。

代码演示:

#include<stdio.h>#define test(x,format) printf(#x "= %" #format "\n", x)int main() {const char* name = "wxf";test(name,s);            //s       相当于 %sint i = 1;test(i, d);      //d   相当于%dreturn 0;
}

结果显示:
在这里插入图片描述

2. 标记的拼接---------(将宏参数进行字符串化和连接操作) :
#define test(x,format) printf(#x "= %" #format "\n", x)#define test2(i) test(age ## i,d)       //d  相当于%d   当然这里可以替换成其他的类型

说明:

在该宏的扩展部分,它将 agei 进行连接操作(使用 ## 连接运算符),形成一个新的标识符,并作为参数传递给 test 宏。

代码演示:

#include<stdio.h>#define test(x,format) printf(#x "= %" #format "\n", x)
#define test2(i) test(age ## i,d)       //d  相当于%d   当然这里可以替换成其他的类型int main() {int age1 = 21,age2=22;test2(1);test2(2);return 0;
}

结果显示:
在这里插入图片描述

3. 宏的嵌套 :

宏的嵌套是我们常用的 , 话不多说,我们直接看例子

#define F(f) f(args)
#define args a,b

说明: 第一个宏里面的f ,替换成f(args), 然后下一个宏,将args ,替换成 a, b 。两者嵌套

代码演示:

#define F(f) f(args)
#define args a,bvoid test3(int number1, int number2) {printf(" %d + %d= %d\n ", number1, number2 , number1+ number2 );
}int main() {int a = 21,b=22;F(test3);return 0;
}

结果显示:
在这里插入图片描述

4. 替换多条语句:
#define YUE_HUIU(name) do {                           \   printf("%s ,我们一起去看电影把!\n , name);       \printf("%s, 我们一起去唱歌吧!\n ", name);      \printf("%s, 我们一起回家吧!\n", name);          \
}while (0);

注意: 使用了 do...while(0) 结构来创建一个匿名的代码块,目的是为了让宏展开后能够正常使用分号进行语句结束。这种技巧可以避免在使用宏时造成错误的语法解析。

代码演示:

/*  '\' 表示续航符,表明这一行还没有结束   */#define YUE_HUIU(name) do {                           \   printf("%s ,我们一起去看电影把!\n , name);       \printf("%s, 我们一起去唱歌吧!\n ", name);      \printf("%s, 我们一起回家吧!\n", name);          \
}while (0);int main() {YUE_HUI("wxf");return 0;
}

结果显示—(宏展开后的样子):

do {printf("%s ,我们一起去看电影把!\n , "wxf");     printf("%s,我们一起去唱歌吧!\n ", "wxf");         printf("%s, 我们一起回家吧!\n", "wxf"); } while (0);
5. 防止头文件被重复包含

这个用法还是经常会用到的 ,我们经常会使用到一些自己定义的 头文件

代码演示:

#ifndef _TOOLS_H     /* tools.h   头文件的名称   */
#ifdef  _TOOLS_H//头文件内容#endif //  _TOOLS_H
6 . 宏和函数的区别
  • 函数调用时,先求出实参表达式的值,然后带入形参, 带参数的宏只是进行简单的字符替换.
  • 函数调用是在程序运行时处理,分配临时内存, 而宏展开(函函数),是在编译时进行的,展开时是不分配内存,也没有返回值,也没 有值传递.
  • 宏的参数没有类型 ,只是一个符号 ,展开时带入到指定的字符串中.
  • 使用宏的次数多时, 宏展开后源程序变长 ,函数调用不会使源程序变长.
  • 宏替换只会占用编译时间 ,不会占用运行时间,而函数调用占用的是运行时间(分配内存 ,传递参数 ,执行函数体).
    时进行的,展开时是不分配内存,也没有返回值,也没有值传递.
  • 宏的参数没有类型 ,只是一个符号 ,展开时带入到指定的字符串中.
  • 使用宏的次数多时, 宏展开后源程序变长 ,函数调用不会使源程序变长.
  • 宏替换只会占用编译时间 ,不会占用运行时间,而函数调用占用的是运行时间(分配内存 ,传递参数 ,执行函数体).

相关文章:

C语言大佬的必杀技---宏的高级用法

C语言大佬的必杀技—宏的高级用法 目录: 字符串化标记的拼接宏的嵌套替换多条语句防止一个文件被重复包含宏和函数的区别 可能大家在学习的时候用得比较少&#xff0c;但是在一些代码量比较大的时候&#xff0c;这样使用&#xff0c;可以大大的提高代码的可读性&#xff0c;…...

@Retryable和Guava retry

文章目录 一、spring的Retryable1.1 作用&#xff1a;1.2链接&#xff1a;https://www.cnblogs.com/EasonJim/p/7684649.html1.3 坑1.4 Recover补充依赖 二、Guava-retry&#xff1a;使用 一、spring的Retryable 1.1 作用&#xff1a; Retryable注解&#xff0c;被注解的方法…...

conda的安装和使用

参考资料&#xff1a; https://www.bilibili.com/read/cv8956636/?spm_id_from333.999.0.0 https://www.bilibili.com/video/BV1Mv411x775/?spm_id_from333.999.0.0&vd_source98d31d5c9db8c0021988f2c2c25a9620 目录 conda是啥以及作用conda的安装conda的启动conda的配置…...

K8S:pod集群调度及相关操作

文章目录 一.pod集群调度概念1.调度约束( List-Watch组件)2.List-Watch的工作机制&#xff08;1&#xff09;List-Watch的工作机制流程&#xff08;2&#xff09;List-Watch的工作机制图示 3.调度的过程&#xff08;1&#xff09;调度的任务&#xff08;2&#xff09;调度选择p…...

阿里云便宜服务器2核2G配置经济型e实例一年182元性能测评

阿里云服务器经济型e实例2核2G配置优惠价格182.04元一年&#xff0c;系统盘ESSD Entry盘20GB起&#xff0c;公网带宽默认按使用流量&#xff0c;也可以选择按固定带宽计费&#xff0c;带宽值从1M到100M可选&#xff0c;阿腾云分享阿里云服务器2核2G优惠价格、详细配置及e系列CP…...

资讯| 工信部拟筹建元宇宙标准化工作组;《权游》作者起诉OpenAI

元宇宙赛道 工信部&#xff1a;优先开展“元宇宙 工业制造”等行业应用标准研制 9月18日&#xff0c;工业和信息化部科技司就《工业和信息化部元宇宙标准化工作组筹建方案&#xff08;征求意见稿&#xff09;》&#xff08;以下简称《方案》&#xff09;公开征求意见。 工业…...

Win10安装Docker Desktop并运行Tutorial示例

背景 前段时间一个项目需要在开发环境直接使用 Docker &#xff0c;为了省事便计划在本地安装 Desktop 版的 Docker 。其实安装过程比较简单&#xff0c;可视化安装即可&#xff0c;主要是对安装与初步使用时遇到的问题做个记录。 下载安装 下载地址&#xff1a;https://dow…...

1、靶机——Pinkys-Place v3(1)

文章目录 一、环境二、获取flag11、扫描局域网内存活主机1.1 查看kali的IP地址1.2 扫描存活主机 2、粗略扫描靶机端口&#xff08;服务&#xff09;3、寻找ftp服务漏洞4、扫描端口详细信息5、匿名登录ftp 一、环境 攻击机&#xff1a;kali 靶机&#xff1a;Pinkys-Place v3&am…...

【AIGC】Stable Diffusion Prompt 每日一练0916

一、前言 1.1 写在前面 本文是一个系列&#xff0c;有点类似随笔&#xff0c;每天一次更新&#xff0c;重点就Stable Diffusion Prompt进行专项训练&#xff0c;本文是第022篇《Stable Diffusion Prompt 每日一练0916》。上一篇《Stable Diffusion Prompt 每日一练0915》 1.…...

【C语言】指针经典笔试题(上)

C语言的一大重头戏就是指针。 对于指针有一些认识&#xff1a; 1.指针是存放变量的地址&#xff0c;一般说的指针和指针变量是一个概念。 2.地址的单位是字节&#xff0c;大小在不同编译器环境下有所不同&#xff0c;32位机器是4个字节&#xff0c;64位机器是8个字节。 3.数组名…...

缓存问题解决方案

《服务器开发技术、方法与实用解决方案》 一、缓存预热 在系统刚启动或活动刚开始时&#xff0c;如果缓存中没有数据&#xff0c;那么大量请求将直接访问数据库。如果瞬时访问流量巨大&#xff0c;则可能导致数据库因过载而宕机&#xff0c;甚至引发系统雪崩。因此需要将缓存…...

数据结构————寻路算法

(一)基础补充 二维数组 定义:基本概念与方法和一维数组相似,一般形式为:类型符 数组名[常量表达式][常量表达式]; 其中,数组长度只能是常量;通常把二维数组第一个下标理解成行,第二个下标为列,常量表达式: 表达式里面只有常量的式子(如数字类常量); 二维数组常…...

蓝桥杯 题库 简单 每日十题 day7

01 啤酒和饮料 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。啤酒每罐2.3元&#xff0c;饮料每罐1.9元。小明买了若干啤酒和饮料&#xff0c;一共花了82.3元。我们还知道他买的啤酒比饮料的数量少&#xff0c;请你…...

go -- 获取当前24点的时间戳 --chatGpt

gpt: 要获取当前24点的时间戳&#xff0c;你可以使用 Go 标准库中的 time 包来实现。以下是一个示例函数&#xff0c;它可以获取当前日期的24点的时间戳&#xff1a; go package main import ( "fmt" "time" ) func getMidnightTimestamp() in…...

docker 容器内手动设置服务自启动

需求描述&#xff1a;不使用DockerFile实现容器内的服务自动启动 1、创建执行程序,以crond为例 //进入容器xxx docker exec -it xxx /bin/sh //切换root账户 bash //创建自动执行文件 vim /root/cron.sh2、自动执行文件内容 crond start3、修改执行文件权限 chmod x /root/…...

腾讯云微服务平台 TSF 异地多活单元化能力重磅升级

导语 2023腾讯全球数字生态大会已于9月7-8日完美落幕&#xff0c;40专场活动展示了腾讯最新的前沿技术、核心产品、解决方案。 微服务与消息队列专场&#xff0c;腾讯云微服务平台 TSF 产品经理张桢带来了《腾讯云微服务平台 TSF 异地多活单元化能力重磅升级》的精彩演讲。本…...

01贪心:算法理论知识

贪心&#xff1a;01算法理论知识 什么是贪心 贪心的本质是选择每一阶段的局部最优&#xff0c;从而达到全局最优。 这么说有点抽象&#xff0c;来举一个例子&#xff1a; 例如&#xff0c;有一堆钞票&#xff0c;你可以拿走十张&#xff0c;如果想达到最大的金额&#xff0…...

目标分类笔记(二): 利用PaddleClas的框架来完成多标签分类任务(从数据准备到训练测试部署的完整流程)

文章目录 一、演示多分类效果二、PaddleClas介绍三、代码获取四、数据集获取五、环境搭建六、数据格式分析七、模型训练7.1 模型恢复训练7.2 多卡训练7.3 其他训练指标 八、模型预测九、模型评估十、PaddleClas相关博客 一、演示多分类效果 二、PaddleClas介绍 PaddleClas主要…...

PageHelp插件在复杂sql下引起的Having无法识别错误及其解决方案

1: 问题出现的场景 系统中有一个复杂SQL内嵌套了多个子查询.在改动时需要将SQL的最后一行加上having来做额外的过滤处理. 添加完having语句后发现SQL能够正常执行就直接将代码提交到了测试环境.结果在测试环境报错Unknown column ‘xxx‘ in ‘having clause. 2: 分析问题 1…...

linux中的开发工具

在刚开始使用linux的时候&#xff0c;我们需要在系统上写一些简单的代码&#xff0c;来熟悉环境以及各种指令 并且熟悉属于linux的一套开发的环境&#xff0c;而这对于c来说需要三个软件就可以进行简单的编码 和使用&#xff0c;让我们来认识一下下列工具&#xff0c;以及工具的…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

OpenLayers 分屏对比(地图联动)

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能&#xff0c;和卷帘图层不一样的是&#xff0c;分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Android写一个捕获全局异常的工具类

项目开发和实际运行过程中难免会遇到异常发生&#xff0c;系统提供了一个可以捕获全局异常的工具Uncaughtexceptionhandler&#xff0c;它是Thread的子类&#xff08;就是package java.lang;里线程的Thread&#xff09;。本文将利用它将设备信息、报错信息以及错误的发生时间都…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...