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过拟合(overfitting)与欠拟合(underfitting)集成学习为什么有效?Blending 模型集成Stakcing 模型集成Bagging模型集成Bagging 模型集成算法流程:Boosting模型集成作业 前言 …...
Max AI prompt2:
1,prompt1——总体概览 “请根据以下指导原则撰写文献解读,特别关注作者的研究思路和方法论: 1. 研究背景与目的: 概述文章研究的背景,明确研究的主要目的和研究问题。 2. 研究思路: 详细描述作者如何构建…...
[Unity Shader][图形渲染]【游戏开发】 Shader数学基础8 - 齐次坐标
在计算机图形学中,齐次坐标是一种方便计算和表示几何变换的方式。通过将三维空间中的 33矩阵扩展为 44的形式,可以统一表示平移、旋转、缩放等几何变换操作。在本篇文章中,我们将详细解析齐次坐标的定义及其在图形变换中的应用。 什么是齐次坐标? 齐次坐标的核心思想是通过…...
挑战一个月基本掌握C++(第十二天)了解命名空间,模板,预处理器
一 命名空间 假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。 同样的情况也出现在 …...
python实现根据搜索关键词爬取某宝商品信息
当程序打开淘宝登陆页面后,需要快速手动登录淘宝,如果服务报错,需要重新登录! pip安装库 pip install pyquery pip install selenium pip install openpyxl # 代码说明:代码功能: 基于ChromeDriver爬取tao…...
Posison Distribution
泊松分布 (Poisson Distribution) 泊松分布是概率论中的一个重要离散分布,描述单位时间或单位空间内随机事件发生的次数,假设事件是独立的且平均发生率是已知的。 定义 泊松分布的概率质量函数 (PMF) 为: P ( X k ) λ k e − λ k ! , …...
2024年最新多目标优化算法:多目标麋鹿群优化算法(MOEHO)求解ZDT1-ZDT4,ZDT6及工程应用---盘式制动器设计,提供完整MATLAB代码
一、麋鹿群优化算法 麋鹿群优化算法(Elephant Herding Optimization,EHO)是2024年提出的一种启发式优化算法,它的灵感来自麋鹿群的繁殖过程。麋鹿有两个主要的繁殖季节:发情和产犊。在发情季节,麋鹿群分裂…...
使用Webpack构建微前端应用
英文社区对 Webpack Module Federation 的响应非常热烈,甚至被誉为“A game-changer in JavaScript architecture”,相对而言国内对此热度并不高,这一方面是因为 MF 强依赖于 Webpack5,升级成本有点高;另一方面是国内已…...
Apache RocketMQ 5.1.3安装部署文档
官方文档不好使,可以说是一坨… 关键词:Apache RocketMQ 5.0 JDK 17 废话少说,开整。 1.版本 官网地址,版本如下。 https://rocketmq.apache.org/download2.配置文件 2.1namesrv端口 在ROCKETMQ_HOME/conf下 新增namesrv.pro…...
CMS(Concurrent Mark Sweep)垃圾回收器的具体流程
引言 CMS(Concurrent Mark Sweep)收集器是Java虚拟机中的一款并发收集器,其设计目标是最小化停顿时间,非常适合于对响应时间敏感的应用。与传统的串行或并行收集器不同,CMS能够尽可能地让垃圾收集线程与用户线程同时运…...
【Linux】Socket编程-UDP构建自己的C++服务器
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 UDP 网络编程 🦋 接口讲解🦋 V1 版本 - echo server🦋 V2 版本 - DictServer🦋 V3 版本 - 简单聊天室 二&a…...
磁盘结构、访问时间、调度算法
目录 一、什么是磁盘? 二、磁盘分类 1、从磁头分 2、通过盘面分 三、一次磁盘读/写的时间 四、磁盘调度算法 1、先来先到服务算法FCFS 2、最短寻找时间优先SSTF 3、扫描算法(SCAN) 4、LOOk算法 5、循环扫描算法(C-SCAN…...
详解归并排序
归并排序 归并排序的基本概念归并排序的详细步骤1. 分解阶段2. 合并阶段3. 归并排序的递归流程 时间复杂度分析空间复杂度分析算法步骤2-路归并排序代码分析代码讲解1. 合并两个子数组的函数 merge()2. 归并排序函数 mergeSort()3. 打印数组的函数 printArray()4. 主函数 main(…...
45.在 Vue 3 中使用 OpenLayers 鼠标点击播放视频
引言 在 Web 开发中,地图可视化和互动功能是越来越重要的应用场景。OpenLayers 是一个强大的开源 JavaScript 库,用于显示和处理地图数据,支持多种地图服务和交互功能。在这个教程中,我们将介绍如何在 Vue 3 中集成 OpenLayers&a…...
《大话Java+playWright》系列教程初级篇-初识
后续代码会整理开源-大家期待吧!!! 首先讲下为啥不用python,因为不想下载各种安装插件,太麻烦了,好多不兼容。 所以选择了java。 先来讲下什么是playwright,playwright是微软开源自动化测试工…...
05.HTTPS的实现原理-HTTPS的握手流程(TLS1.2)
05.HTTPS的实现原理-HTTPS的握手流程(TLS1.2) 简介1. TLS握手过程概述2. TLS握手过程细化3. 主密钥(对称密钥)生成过程4. 密码规范变更 简介 主要讲述了混合加密流程完成后,客户端和服务器如何共同获得相同的对称密钥…...
提示词工程
一、六何分析法快速写出准确的提示词 英文单词中文解释提问时的思考示例Why何故问题的背景,包括为什么做及目标(做成什么样)最近我们要与某品牌合作推广冲牙器,对方需要我们策划一场营销活动What何事具体是什么事写一个营销策划方…...
基于python网络爬虫的搜索引擎设计
一、毕业设计(论文)题目:基于网络爬虫的搜索引擎设计 - 基于网络爬虫的搜索引擎设计1 二、毕业设计(论文)工作自 2022-09-01 起至 2022-10-28 止 三、毕业设计(论文)内容要求: 主…...
ip-协议
文章目录 1. 网络层2. ip协议2.1 ip协议格式2.2 网段划分基本概念网段划分的两种方式为什么要网段划分?特殊的IP地址IP地址数量不足 2.3 私有IP与公网IP2.4 路由 3. IP的分片与组装为什么要分片与组装?如何分片?如何组装? 1. 网络…...
Zellij远程认证终极指南:OAuth、SSH与令牌管理全解析
Zellij远程认证终极指南:OAuth、SSH与令牌管理全解析 【免费下载链接】zellij A terminal workspace with batteries included 项目地址: https://gitcode.com/gh_mirrors/ze/zellij 欢迎来到Zellij终端工作区的远程认证世界!🚀 Zelli…...
【Agent】Microsoft Agent Framework 实战:打造智能 Git 周报生成工具
Microsoft Agent Framework 实战:打造智能 Git 周报生成工具从手动写周报到 AI 自动生成,用 Python Microsoft Agent Framework RC6 构建你的第一个 Agent 应用一、前言:程序员周报的痛点 每周五下班前,你是不是都在对着 Git 提交…...
星光护航 家校同行 多方联合点亮4·2世界孤独症日公益之光
2026年4月2日第19个世界孤独症关注日来临之际,联合国官宣年度主题Autism and Humanity — Every Life Has Value(孤独症与人类 — 每一个生命都弥足珍贵),中国同步确定“提质全生涯服务供给,聚焦孤独症家庭支持与成年服…...
PLC控制四轴攻丝机全伺服工程案例(含接线图):附带启动停止原点定位等控制指令详解及文本屏即用程序
plc控制伺服电机 四轴攻丝机案例(包含伺服接线图) 该程序为plc控制伺服电机的工程案例包含伺服电机接线图,包含程序流程的详细解释说明 程序包括伺服电机的启动,停止,原点定位,回归原点,位置控制以及方向控制包括了所有…...
3个维度解锁抖音内容采集:从个人创作到企业运营的效率革命
3个维度解锁抖音内容采集:从个人创作到企业运营的效率革命 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback s…...
如何利用Clef Handbook进行有效会议管理:5个关键原则 [特殊字符]
如何利用Clef Handbook进行有效会议管理:5个关键原则 🚀 【免费下载链接】handbook An employee handbook built for inclusion 项目地址: https://gitcode.com/gh_mirrors/handbook6/handbook 在当今快节奏的工作环境中,高效会议管理…...
nlp_structbert_sentence-similarity_chinese-large 与传统方法对比:TF-IDF、Word2Vec与深度语义模型
nlp_structbert_sentence-similarity_chinese-large 与传统方法对比:TF-IDF、Word2Vec与深度语义模型 1. 引言 在中文文本处理的世界里,判断两句话是不是一个意思,一直是个挺有意思的挑战。比如,“今天天气真好”和“今日阳光明…...
无人机 Remote ID(RID)广播与技术标准概览
无人机 Remote ID(RID)广播与技术标准概览 目录 概述与知识地图一、RID 广播是什么二、广播内容与工作方式三、广播式 RID 与网络式 RID四、技术要点:频段、功率、硬件与协议五、Open Drone ID / ASTM 报文体系(扩展)…...
从 CLI 调用到 SDK 集成:GitHub Copilot 在 .NET 项目中的最佳实践
从 CLI 调用到 SDK 集成:GitHub Copilot 在 .NET 项目中的最佳实践 从命令行调用到官方 SDK 集成的升级之路,说起来也算是一段经历,今天就分享我们在 HagiCode 项目中踩过的坑和学到的东西。 背景 GitHub Copilot SDK 在 2025 年正式发布后&…...
避坑指南:QML调用C++时那些让你debug到崩溃的隐藏问题(Qt5/6通用)
QML与C交互避坑实战:信号槽、内存管理与类型转换的终极解决方案 第一次在QML中调用C对象时,那种跨语言调用的兴奋感很快会被各种诡异问题冲淡——信号死活不触发、对象莫名其妙被销毁、类型转换时程序崩溃...这些问题往往让开发者陷入数小时的debug泥潭。…...
