#define宏定义的初探
前言:
最基本的#define定义方式
#define可以定义宏,这点相信大家并不陌生,其定义的方式十分简单,给大家随便来一个最简单、最基础的定义方式看看:
#include<stdio.h>
#define a 3
int main()
{
printf("%d",a);
return 0;
}
在这个代码中,我们使用#define定义了a为3,然后我们在主函数中打印a的值,注意,我们不需要创建a这个变量,就可以直接将a打印,并且语法完全正确,没有任何警告和报错,看似十分的神奇,但这就是#define定义宏的最简单的定义方式。
稍加难度的定义方式
显而易见的是,这种定义方式未免有点太简单了,所以说能够实现的功能和使用的环境也是十分简单的,但我们就了解这种简单的方式是远远不够的,我们需要稍加深入的探讨一下#define的定义方式:
#include<stdio.h>
#define sum(a,b) a+b
int main()
{int x, y;scanf("%d%d", &x, &y);printf("%d", sum(x, y));return 0;
}
这就有点初步具有宏的样子了,我们定义sum,需要的值是a和b,然后sum为a+b;这是什么意思呢,其实不难——编译器将我们的代码跑起来需要经过预处理、汇编、链接等复杂的步骤,这其中的内容很丰富,我具体没有深入的研究,但是有一点可以确定——在预处理的时候,编译器就自动将我们#define定义的宏给替换了,就用这个代码来说说——我们写到sum(x,y),在预处理的时候,编译器就会自动的将其改为sum(x,y)==a+b,(a就是x,b就是y),所以说sum(x+y)=x+y;打印的自然就是x+y的值了。
#define中也可以包含函数
define中是可以包含函数的,举个例子:
#include<stdio.h>
#define a printf("hehe")
int main()
{a;return 0;
}
当我们使用a的时候,在预处理的时候编译器就会将a改为printf("hehe");所以说就会打印hehe,还是十分的神奇,但注意一点,#define虽然可以包含函数,但绝对不能进行递归操作!
再加点难度的#define宏
让我们再开动一下脑筋,加一点难度:
#include<stdio.h>
#define sz(type) printf("hehe\t"#type"的大小为%d\n",(int)sizeof(type))
int main()
{sz(char);return 0;
}
//#define num(a,type) printf("thenumberis"#a"="#type,a)
//int main()
//{
// num(2,%d);
// return 0;
//}
我们给sz这个宏传的是type(数据类型),然后通过sizeof操作符(注意:sizeof是操作符,不是函数)算出其大小,并通过printf打印,#define其实是起到了一个替换的作用,在printf中打印#type就会被替换为你传过去的东西,所以这串代码打印出来就是:
同样的道理,下面一个程序,我们传过去一个数字,和打印的格式,预处理之后,就会被替换成你传的数字和你想要打印的格式,十分的方便。
#define的特殊用法
1.##
介绍一下#define中特殊的用法——##(我认为算是特殊用法)
#define like(a,b) a##b
int main()
{int hah = 520;printf("%d", like(ha, h));return 0;
}
这个程序会输出520,我们看宏——传的是两个值a、b,而a##b的意思是将二者连起来,相当于ab(如果ab是两个字符串的话),我们在主函数中定义变量hah为520,然后打印like(ha,h),显而易见的是,经过宏,就已经成了hah ,而hah就是520,所以说自然会打印出520。而我们也可以知道##就是起到一个连接的作用。
2.类似if和else的用法
这个我不想多讲,因为我不知道在实际运用中有什么价值,还挺别扭的:
int main()
{
#if 2==3printf("haha");
#endif
#if 2!=3printf("hehe");
#endif
}
这个#if其实和if很像啊,我就是像理解if一样来理解#if的,但有点不同:首先、有了#if就一定要有#endif,不然编译器会报错;其次、#if不能有变量之间的运算,所以说#if完全没用if使用起来方便。
后记
其实说了这么多,也学了这么多,我总感觉#define定义宏和函数的调用有什么异曲同工之妙,但其实想想各有优劣吧:#define适合定义一些简单的运算,当遇到一些简单的代码,推荐使用#define定义宏来写。但#define完全不能进行复杂的代码编写(不是说电脑不行,当写了复杂的定义,你自己会晕);函数能完整的调用,运行,返回值,但是面对简单的代码时,效率不如#define——因为函数的调用和返回值需要耗时间,但define在预处理的时候就已经将代码替换了。
所以说遇到复杂代码推荐使用函数。“因地制宜,因材施教”将#define和我们学过的知识所结合,才能够让我们的编程变得越来越好。
相关文章:
#define宏定义的初探
前言: 最基本的#define定义方式 #define可以定义宏,这点相信大家并不陌生,其定义的方式十分简单,给大家随便来一个最简单、最基础的定义方式看看: #include<stdio.h> #define a 3 int main() { printf(&quo…...
机器学习 -决策树的案例
场景 我们对决策树的基本概念和算法其实已经有过了解,那我们如何利用决策树解决问题呢? 构建决策树 数据准备 我们准备了一些数据如下: # 定义新的数据集 new_dataSet [[晴朗, 是, 高, 是],[雨天, 否, 低, 否],[阴天, 是, 中, 是],[晴朗…...
04、Kafka ------ 各个功能的作用解释(Cluster、集群、Broker、位移主题、复制因子、领导者副本、主题)
目录 启动命令:CMAK的用法★ 在CMAK中添加 Cluster★ 在CMAK中查看指定集群★ 在CMAK中查看 Broker★ 位移主题★ 复制因子★ 领导者副本和追随者副本★ 查看主题 启动命令: 1、启动 zookeeper 服务器端 小黑窗输入命令: zkServer 2、启动 …...
1、C语言:数据类型/运算符与表达式
数据类型/运算符/表达式 1.数据类型与长度2.常量3.声明4. 运算符5. 表达式 1.数据类型与长度 基本数据类型 类型说明char字符型,占用一个字节,可以存放本地字符集中的一个字符int整型,通常反映了所有机器中整数的最自然长度float单精度浮点…...
[ffmpeg系列 03] 文件、流地址(视频)解码为YUV
一 代码 ffmpeg版本5.1.2,dll是:ffmpeg-5.1.2-full_build-shared。x64的。 文件、流地址对使用者来说是一样。 流地址(RTMP、HTTP-FLV、RTSP等):信令完成后,才进行音视频传输。信令包括音视频格式、参数等协商。 接流的在实际…...
python算法每日一练:连续子数组的最大和
这是一道关于动态规划的算法题: 题目描述: 给定一个整数数组 nums,请找出该数组中连续子数组的最大和,并返回这个最大和。 示例: 输入:[-2, 1, -3, 4, -1, 2, 1, -5, 4] 输出:6 解释ÿ…...
一个vue3的tree组件
https://download.csdn.net/download/weixin_41012767/88709466...
新手练习项目 4:简易2048游戏的实现(C++)
名人说:莫听穿林打叶声,何妨吟啸且徐行。—— 苏轼《定风波莫听穿林打叶声》 Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder) 目录 一、效果图二、代码(带注释)三、说明 一、效果图 二、代码(带…...
2023年度总结:技术沉淀、持续学习
2023年度总结:技术沉淀、持续学习 一、引言 今年是我毕业的第二个年头,也是完整的一年,到了做年终总结的时候了 这一年谈了女朋友,学习了不少技术,是充实且美好的一年! 首先先看年初定的小目标…...
Unity 利用UGUI之Slider制作进度条
在Unity中使用Slider和Text组件可以制作简单的进度条。 首先在场景中右键->UI->Slider,新建一个Slider组件: 同样方法新建一个Text组件,最终如图: 创建一个进度模拟脚本,Slider_Progressbar.cs using System.C…...
OCS2 入门教程(四)- 机器人示例
系列文章目录 前言 OCS2 包含多个机器人示例。我们在此简要讨论每个示例的主要特点。 System State Dim. Input Dim. Constrained Caching Double Integrator 2 1 No No Cartpole 4 1 Yes No Ballbot 10 3 No No Quadrotor 12 4 No No Mobile Manipul…...
FreeRTOS学习第6篇–任务状态挂起恢复删除等操作
目录 FreeRTOS学习第6篇--任务状态挂起恢复删除等操作任务的状态设计实验IRReceiver_Task任务相关代码片段实验现象本文中使用的测试工程 FreeRTOS学习第6篇–任务状态挂起恢复删除等操作 本文目标:学习与使用FreeRTOS中的几项操作,有挂起恢复删除等操作…...
BLE Mesh蓝牙组网技术详细解析之Access Layer访问层(六)
目录 一、什么是BLE Mesh Access Layer访问层? 二、Access payload 2.1 Opcode 三、Access layer behavior 3.1 Access layer发送消息的流程 3.2 Access layer接收消息的流程 3.3 Unacknowledged and acknowledged messages 3.3.1 Unacknowledged message …...
Netlink 通信机制
文章目录 前言一、Netlink 介绍二、示例代码参考资料 前言 一、Netlink 介绍 Netlink套接字是用以实现用户进程与内核进程通信的一种特殊的进程间通信(IPC) ,也是网络应用程序与内核通信的最常用的接口。 在Linux 内核中,使用netlink 进行应用与内核通信的应用有…...
2024.1.8每日一题
LeetCode 回旋镖的数量 447. 回旋镖的数量 - 力扣(LeetCode) 题目描述 给定平面上 n 对 互不相同 的点 points ,其中 points[i] [xi, yi] 。回旋镖 是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的距离和 i 和 k 之间的欧式…...
看了致远OA的表单设计后的思考
更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/n…...
mmdetection训练自己的数据集
mmdetection训练自己的数据集 这里写目录标题 mmdetection训练自己的数据集一: 环境搭建二:数据集格式转换(yolo转coco格式)yolo数据集格式coco数据集格式yolo转coco数据集格式yolo转coco数据集格式的代码 三: 训练dataset数据文件配置config…...
MySQL取出N列里最大or最小的一个数据
如题,现在有3列,都是数字类型,要取出这3列里最大或最小的的一个数字 -- N列取最小 SELECT LEAST(temperature_a,temperature_b,temperature_c) min FROM infrared_heat-- N列取最大 SELECT GREATEST(temperature_a,temperature_b,temperat…...
编写.NET的Dockerfile文件构建镜像
创建一个WebApi项目,并且创建一个Dockerfile空文件,添加以下代码,7.0代表的你项目使用的SDK的版本,构建的时候也需要选择好指定的镜像tag FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443F…...
【C语言】浙大版C语言程序设计(第三版) 练习7-4 找出不是两个数组共有的元素
前言 最近在学习浙大版的《C语言程序设计》(第三版)教材,同步在PTA平台上做对应的练习题。这道练习题花了比较长的时间,于是就写篇博文记录一下我的算法和代码。 2024.01.03 题目 练习7-4 找出不是两个数组共有的元素 作者 张彤…...
深入解析PLL锁相环在FPGA时钟管理中的核心应用
1. 从闹钟到芯片:PLL如何成为FPGA的"时间管家" 想象一下你早上起床的场景:手机闹钟准时响起,咖啡机开始自动煮咖啡,窗帘缓缓拉开让阳光照进来。这些设备之所以能完美同步,全靠它们内部精确的时钟信号。而在…...
基于springboot图书综合服务平台设计与开发(源码+精品论文+答辩PPT等资料)
博主介绍:CSDN毕设辅导第一人、靠谱第一人、全网粉丝50W,csdn特邀作者、博客专家、腾讯云社区合作讲师、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交…...
OpenClaw环境迁移:GLM-4.7-Flash配置的备份与恢复方案
OpenClaw环境迁移:GLM-4.7-Flash配置的备份与恢复方案 1. 为什么需要环境迁移? 上周我的主力开发机突然硬盘故障,导致所有OpenClaw配置丢失。最痛心的是花了两周调试的GLM-4.7-Flash对接设置全部归零——包括精心调整的温度参数、自定义提示…...
C#实战:基于WebAPI与Modbus构建EMS核心采集服务
1. 为什么需要EMS核心采集服务? 在工业现场,我们经常会遇到几十台甚至上百台智能电表、传感器等设备需要监控。这些设备可能来自不同厂家,使用不同的通信协议,数据格式也各不相同。想象一下,如果每个设备都需要单独开发…...
MySQL 事务机制深度解析:从 ACID 到底层实现
MySQL 事务机制深度解析:从 ACID 到底层实现 MySQL 的事务机制主要由 InnoDB 存储引擎 实现,核心围绕 ACID 四大特性,通过 日志系统(redo log、undo log)、锁机制 和 MVCC(多版本并发控制) 共同…...
光伏储能管理系统:绿虫赋能,破解行业流程痛点
光伏储能产业迎来高速发展期,但其全业务流程的复杂性却成为企业发展的桎梏。从项目开发的多环节审批,到建设阶段的进度质量管控,再到运维结算的数据协同,各环节割裂、部门协作不畅、数据杂乱无章等问题频发,不少企业负…...
基于springboot的某学院勤工俭学岗位兼职平台设计与实现
目录 技术选型与架构设计核心功能模块划分数据库设计要点关键代码实现示例安全与权限控制测试与部署计划扩展性考虑 项目技术支持源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作 技术选型与架构设计 后端采用SpringBoot框架,集…...
I-Lang SEO实战部署:用结构化协议让Google的AI爬虫读懂你的网页
前言: 我们用I-Lang的结构化方法论做SEO,一个全新的英文商业站,七天打进Google搜索第一页。这篇文章把具体方法公开。 一、前提:Google的爬虫已经是AI了 2024年之后,Google的搜索排名算法发生了根本性变化。Googlebot…...
GNSS说第(八)讲---自适应动态导航定位(八)---抗差估计在复杂环境下的应用实践
1. 抗差估计:GNSS定位的"防弹衣" 想象一下你在高楼林立的城市峡谷中打开手机导航,信号时断时续,定位图标像喝醉酒一样到处乱飘——这就是典型的多路径干扰场景。传统最小二乘法就像用普通尺子测量扭曲的橡皮筋,单个异常…...
一文搞懂训练大模型的数据怎么准备!
谈到大模型,很多人第一反应都是模型参数大、算力强,但其实数据才是大模型真正的底座。没有足够大、足够干净的数据,再先进的模型也发挥不出威力。今天就从数据层面,把大模型训练的几个关键环节梳理清楚。 数据采集与清洗 大模型训…...
