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

7.C语言 宏(Macro) 宏定义,宏函数

目录

宏定义

宏函数

1.注释事项

2.注意事项

宏(Macro)用法

常量定义

简单函数实现

类型检查

条件编译

宏函数计算参数个数

宏定义进行类型转换

宏定义进行位操作

宏定义进行断言

总结


宏定义

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MAX 1025 //定义宏int main() 
{system("pause");return EXIT_SUCCESS;
}

宏函数

宏函数通常将一些比较频繁,短小的函数封装为宏函数。减少一些入栈,出栈的时间消耗。

在C语言中,宏(Macro)是预处理器的一种功能,它允许你定义一种简写形式来代替一段特定的代码。宏定义的基本形式如下:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MYADD(x,y) x + y //宏函数int main() 
{int a = 10;int b = 20;printf("a+b = %d\n",MYADD(a,b));system("pause");return EXIT_SUCCESS;
}

运行结果:

宏函数在预处理中做了一个替换 就是将 a 和 b替换成x和y。

宏函数是使用宏定义的函数风格的宏。它们可以像普通函数那样调用,但最终会被预处理器替换成相应的代码,减少入栈,出栈的时间。

1.注释事项

宏函数要保证运算的完整性才能执行,可以查看下面代码处理流程

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MYADD(x,y) x + y //宏函数int main() 
{int a = 10;int b = 20;int result = MYADD(a, b) * 10;printf("result = %d\n", result);system("pause");return EXIT_SUCCESS;
}

打印结果

从上面结果来看,10 + 20 * 10 结果是等于300才符合我们预期,这个是运算完整性导致的。就是先乘除后加减问题

这个问题是可以解决的,通过()来处理,

#define MYADD(x,y) ((x) + (y)) //宏函数

2.注意事项

宏函数在一定的程度上会比普通的函数效率高

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MYADD(x,y) ((x) + (y)) //宏函数void myAdd(int x,int y) { //x会在栈上定义,y也会 . 所以宏函数会有一定优势return x + y;
}int main() 
{int a = 10;int b = 20;int result = MYADD(a, b) * 10;printf("result = %d\n", result);system("pause");return EXIT_SUCCESS;
}

可以从宏函数,和普通函数对比,一个没有栈的开销,一个有开销。

普通函数会有入栈和出栈时间上的开销

宏(Macro)用法

常量定义

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MAX 1024int main() 
{printf("MAX = %d\n", MAX);system("pause");return EXIT_SUCCESS;
}

运行结果

有参数宏

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MYADD(x,y) ((x) + (y)) //宏函数int main() 
{int a = 10;int b = 20;int result = MYADD(a, b);printf("result = %d\n", result);system("pause");return EXIT_SUCCESS;
}

运行结果:

宏运算链接符

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MAX 100
#define ROW 100
#define GET_MAX(x,y) \
x = x+y;\
y = x+y;int main() 
{int a = 10;int b = 10;GET_MAX(a, b)printf("random %d  %d\n\n", a,b);system("pause");return EXIT_SUCCESS;
}

从上面代码来看\表示链接符号,运行完第一个,就执行第二个

 无参数宏

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define MAX 100
#define ROW 100
#define RANDOM (-1.0 + 2.0*(double)rand() / RAND_MAX)int main() 
{int v = 10;printf("random %lf\n\n",RANDOM);system("pause");return EXIT_SUCCESS;
}

类型检查

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define CHECK_TYPE(a) generic((a), \int: printf("int"), \char: printf("char"), \float: printf("float"), \default: printf("other type") \
)int main() 
{int v = 10;//CHECK_TYPE(v);printf("%s", _Generic(v));system("pause");return EXIT_SUCCESS;
}

条件编译

#include "stdio.h"
#include "string.h"
#include "stdlib.h"#define DEBUG#ifdef DEBUG
#define PRINT_DEBUG(fmt, ...) printf(fmt, ##__VA_ARGS__)
#else
#define PRINT_DEBUG(fmt, ...)
#endifint main() 
{int v = 10;char value[] = "达帮主";PRINT_DEBUG("%s\n",value);system("pause");return EXIT_SUCCESS;
}

运行结果:

如果删掉define就不会有打印

宏函数计算参数个数

#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME
#define VA_SIZE(...) \GET_MACRO(__VA_ARGS__, 4, 3, 2, 1, 0)#define SHOW_PARAM_COUNT(...) \printf("Number of parameters: %d\n", VA_SIZE(__VA_ARGS__))// 使用
SHOW_PARAM_COUNT(1, 2); // 输出:Number of parameters: 2

宏定义进行类型转换

#define CONTAINER_OF(ptr, type, member) \((type *)((char *)(ptr) - (char *) &((type *)0)->member))

宏定义进行位操作

#define SET_BIT(x, bit) ((x) |= (1 << (bit)))
#define CLEAR_BIT(x, bit) ((x) &= ~(1 << (bit)))
#define FLIP_BIT(x, bit) ((x) ^= (1 << (bit)))
#define GET_BIT(x, bit) (((x) >> (bit)) & 1)

宏定义进行断言

#define ASSERT(expr) \if (!(expr)) { \printf("Assertion failed: %s\n", #expr); \exit(1); \}

总结

1.宏函数要保证运算的完整性。

2.宏函数在一定程度上,会比普通函数效率高,普通函数会有入栈和出栈时间上的开销。

3.通常会吧调用频繁的,短小的函数封装为宏函数。

4.宏函数的优点,以空间换时间。

相关文章:

7.C语言 宏(Macro) 宏定义,宏函数

目录 宏定义 宏函数 1.注释事项 2.注意事项 宏(Macro)用法 常量定义 简单函数实现 类型检查 条件编译 宏函数计算参数个数 宏定义进行类型转换 宏定义进行位操作 宏定义进行断言 总结 宏定义 #include "stdio.h" #include "string.h" #incl…...

4.系统学习-集成学习

集成学习 前言Bias and Variance过拟合&#xff08;overfitting&#xff09;与欠拟合&#xff08;underfitting&#xff09;集成学习为什么有效&#xff1f;Blending 模型集成Stakcing 模型集成Bagging模型集成Bagging 模型集成算法流程&#xff1a;Boosting模型集成作业 前言 …...

Max AI prompt2:

1&#xff0c;prompt1——总体概览 “请根据以下指导原则撰写文献解读&#xff0c;特别关注作者的研究思路和方法论&#xff1a; 1. 研究背景与目的&#xff1a; 概述文章研究的背景&#xff0c;明确研究的主要目的和研究问题。 2. 研究思路&#xff1a; 详细描述作者如何构建…...

[Unity Shader][图形渲染]【游戏开发】 Shader数学基础8 - 齐次坐标

在计算机图形学中,齐次坐标是一种方便计算和表示几何变换的方式。通过将三维空间中的 33矩阵扩展为 44的形式,可以统一表示平移、旋转、缩放等几何变换操作。在本篇文章中,我们将详细解析齐次坐标的定义及其在图形变换中的应用。 什么是齐次坐标? 齐次坐标的核心思想是通过…...

挑战一个月基本掌握C++(第十二天)了解命名空间,模板,预处理器

一 命名空间 假设这样一种情况&#xff0c;当一个班上有两个名叫 Zara 的学生时&#xff0c;为了明确区分它们&#xff0c;我们在使用名字之外&#xff0c;不得不使用一些额外的信息&#xff0c;比如他们的家庭住址&#xff0c;或者他们父母的名字等等。 同样的情况也出现在 …...

python实现根据搜索关键词爬取某宝商品信息

当程序打开淘宝登陆页面后&#xff0c;需要快速手动登录淘宝&#xff0c;如果服务报错&#xff0c;需要重新登录&#xff01; pip安装库 pip install pyquery pip install selenium pip install openpyxl # 代码说明&#xff1a;代码功能&#xff1a; 基于ChromeDriver爬取tao…...

Posison Distribution

泊松分布 (Poisson Distribution) 泊松分布是概率论中的一个重要离散分布&#xff0c;描述单位时间或单位空间内随机事件发生的次数&#xff0c;假设事件是独立的且平均发生率是已知的。 定义 泊松分布的概率质量函数 (PMF) 为&#xff1a; P ( X k ) λ k e − λ k ! , …...

2024年最新多目标优化算法:多目标麋鹿群优化算法(MOEHO)求解ZDT1-ZDT4,ZDT6及工程应用---盘式制动器设计,提供完整MATLAB代码

一、麋鹿群优化算法 麋鹿群优化算法&#xff08;Elephant Herding Optimization&#xff0c;EHO&#xff09;是2024年提出的一种启发式优化算法&#xff0c;它的灵感来自麋鹿群的繁殖过程。麋鹿有两个主要的繁殖季节&#xff1a;发情和产犊。在发情季节&#xff0c;麋鹿群分裂…...

使用Webpack构建微前端应用

英文社区对 Webpack Module Federation 的响应非常热烈&#xff0c;甚至被誉为“A game-changer in JavaScript architecture”&#xff0c;相对而言国内对此热度并不高&#xff0c;这一方面是因为 MF 强依赖于 Webpack5&#xff0c;升级成本有点高&#xff1b;另一方面是国内已…...

Apache RocketMQ 5.1.3安装部署文档

官方文档不好使&#xff0c;可以说是一坨… 关键词&#xff1a;Apache RocketMQ 5.0 JDK 17 废话少说&#xff0c;开整。 1.版本 官网地址&#xff0c;版本如下。 https://rocketmq.apache.org/download2.配置文件 2.1namesrv端口 在ROCKETMQ_HOME/conf下 新增namesrv.pro…...

CMS(Concurrent Mark Sweep)垃圾回收器的具体流程

引言 CMS&#xff08;Concurrent Mark Sweep&#xff09;收集器是Java虚拟机中的一款并发收集器&#xff0c;其设计目标是最小化停顿时间&#xff0c;非常适合于对响应时间敏感的应用。与传统的串行或并行收集器不同&#xff0c;CMS能够尽可能地让垃圾收集线程与用户线程同时运…...

【Linux】Socket编程-UDP构建自己的C++服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; UDP 网络编程 &#x1f98b; 接口讲解&#x1f98b; V1 版本 - echo server&#x1f98b; V2 版本 - DictServer&#x1f98b; V3 版本 - 简单聊天室 二&a…...

磁盘结构、访问时间、调度算法

目录 一、什么是磁盘&#xff1f; 二、磁盘分类 1、从磁头分 2、通过盘面分 三、一次磁盘读/写的时间 四、磁盘调度算法 1、先来先到服务算法FCFS 2、最短寻找时间优先SSTF 3、扫描算法&#xff08;SCAN&#xff09; 4、LOOk算法 5、循环扫描算法&#xff08;C-SCAN…...

详解归并排序

归并排序 归并排序的基本概念归并排序的详细步骤1. 分解阶段2. 合并阶段3. 归并排序的递归流程 时间复杂度分析空间复杂度分析算法步骤2-路归并排序代码分析代码讲解1. 合并两个子数组的函数 merge()2. 归并排序函数 mergeSort()3. 打印数组的函数 printArray()4. 主函数 main(…...

45.在 Vue 3 中使用 OpenLayers 鼠标点击播放视频

引言 在 Web 开发中&#xff0c;地图可视化和互动功能是越来越重要的应用场景。OpenLayers 是一个强大的开源 JavaScript 库&#xff0c;用于显示和处理地图数据&#xff0c;支持多种地图服务和交互功能。在这个教程中&#xff0c;我们将介绍如何在 Vue 3 中集成 OpenLayers&a…...

《大话Java+playWright》系列教程初级篇-初识

后续代码会整理开源-大家期待吧&#xff01;&#xff01;&#xff01; 首先讲下为啥不用python&#xff0c;因为不想下载各种安装插件&#xff0c;太麻烦了&#xff0c;好多不兼容。 所以选择了java。 先来讲下什么是playwright&#xff0c;playwright是微软开源自动化测试工…...

05.HTTPS的实现原理-HTTPS的握手流程(TLS1.2)

05.HTTPS的实现原理-HTTPS的握手流程&#xff08;TLS1.2&#xff09; 简介1. TLS握手过程概述2. TLS握手过程细化3. 主密钥&#xff08;对称密钥&#xff09;生成过程4. 密码规范变更 简介 主要讲述了混合加密流程完成后&#xff0c;客户端和服务器如何共同获得相同的对称密钥…...

提示词工程

一、六何分析法快速写出准确的提示词 英文单词中文解释提问时的思考示例Why何故问题的背景&#xff0c;包括为什么做及目标&#xff08;做成什么样&#xff09;最近我们要与某品牌合作推广冲牙器&#xff0c;对方需要我们策划一场营销活动What何事具体是什么事写一个营销策划方…...

基于python网络爬虫的搜索引擎设计

一、毕业设计&#xff08;论文&#xff09;题目&#xff1a;基于网络爬虫的搜索引擎设计 - 基于网络爬虫的搜索引擎设计1 二、毕业设计&#xff08;论文&#xff09;工作自 2022-09-01 起至 2022-10-28 止 三、毕业设计&#xff08;论文&#xff09;内容要求&#xff1a; 主…...

ip-协议

文章目录 1. 网络层2. ip协议2.1 ip协议格式2.2 网段划分基本概念网段划分的两种方式为什么要网段划分&#xff1f;特殊的IP地址IP地址数量不足 2.3 私有IP与公网IP2.4 路由 3. IP的分片与组装为什么要分片与组装&#xff1f;如何分片&#xff1f;如何组装&#xff1f; 1. 网络…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf

FTP 客服管理系统 实现kefu123登录&#xff0c;不允许匿名访问&#xff0c;kefu只能访问/data/kefu目录&#xff0c;不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...