活用C语言之宏定义应用大全
零、C语言宏定义知多少
C语言的编程过程中经常会用到宏定义,然而如果你只是使用宏定义做一些常量的定义,那么你不是OUT了就是C语言小白。
那么我们在编程过程中,宏定义都有哪些作用呢?
-
常量定义
-
可以作为功能代码的开关
-
防止头文件被重复包含
-
定义一些通用类型,防止因为平台和编译器不同导致的类型差异,方便移植
-
其他高级浮夸用法
-
。。。。。。
下面,我们来罗列一下宏定义的各种使用方法,建议收藏。
一、常量定义
//定义π值,代码易读
#define PI 3.1415926
//定义常数,不像const修饰的变量要占用空间
#define MAX_LEN 1024
二、防止头文件重复包含
#ifndef COMDEF_H#define COMDEF_H//头文件内容#endif
三、移植利器:重定义数据类型
typedef unsigned char boolean;
typedef unsigned long int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef signed long int int32;
typedef signed short int16;
typedef signed char int8;
四、宏函数
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) //请注意这里的括号,一定要加,否则会有意外惊喜//宏定义实现一个参数交换#define SWAP(X, Y) \X = X +Y; \Y = X - Y; \X = X - Y; //再来看一下求数组的最大最小值是不是非常简洁maxvalue =minvalue = a[0];
for(i = 1; i < MAXLEN; i++)
{ maxvalue = MAX(maxvalue, a[i]); minvalue = MIN(minvalue , a[i]);
}
五、作为功能开关使用
//在调试模式下(DEBUG_MODE在之前被定义)才会将代码编译进去#ifdef DEBUG_MODE ……#endif//可以根据宏定义KEY_ON的真假来选择代码进行编译#if (KEY_ON)
……
#else
……
#endif
六、作为字符串或者连字符使用
在宏体中,如果宏体所在标示符中有##,那么在宏体扩展的时候,宏参数会被直接替换到标示符中。如:
#define COMMAND(NAME) {#NAME, NAME ## _command }struct command
{char *name;void (*function)(void);
};//在宏扩展的时候struct commandcommands[] =
{COMMAND (quit),COMMAND (help),…
};//会被扩展成:struct commandcommands[] =
{{ "quit",quit_command },{ "help",help_command },…
};
这样就节省了大量时间,提高效率。
七、协助调试的宏定义LINE 及 FILE
line指令可以改变它的值,简单的讲,编译时,它们包含程序的当前行数和文件名。
DATE宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
TIME 宏指令包含程序编译的时间。时间用字符串表示,其形式为 时: 分:秒
STDC 宏指令的意义是编译时定义的。一般来讲,如果STDC已经定义,编译器将仅接受不包含任何非标准扩展的标准C/C++代码。如果实现是标准的,则宏STDC含有十进制常量1。如果它含有任何其它数,则实现是非标准的。
#define MAINVER 2
#define SUBVER1 0
#define SUBVER2 1 #define STR(s) #s #define VERSION(a,b,c) "System V" STR(a) "." STR(b) "." STR(c) "."__DATE__//"System V2.0.1.2017.9.13"
八、其他调试用特殊宏定义
//-- 例1.作为块注释,非常的好用,对于一些编辑器,还会自动变灰,方便阅读
#if 0
/*your code, want not use*/
#endif//-- 例2.得到指定地址上的一个字节或字
#define MEM_B(x) (*((byte *) (x)))
#define MEM_W(x) (*((word *) (x)))//-- 例3.得到一个成员变量(field)在结构体(struct)中的偏移量
#define FPOS(type, field) ((dword) &((type *) 0)->field)//-- 例4.得到一个结构体中成员变量(field)所占用的字节数
#define FSIZ(type, field) sizeof(((type *) 0)->field)//-- 例5.按照LSB格式把两个字节转化为一个Word
// 传入的参数需要为数组哦
#define FLIPW(ray) ((((word) (ray)[0]) * 256) + (ray)[1])//-- 例6.按照LSB格式把一个Word转化为两个字节
#define FLOPW(ray, val) (ray)[0] = ((val) / 256); (ray)[1] = ((val) & 0xFF)//-- 例7.得到一个变量的地址(word宽度)
#define B_PTR(var) ((byte *) (void *) &(var))
#define W_PTR(var) ((word *) (void *) &(var))//-- 例8.得到一个字的高位和低位字节
#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))//-- 例9.返回一个比X大的最接近的8的倍数
#define RND8(x) ((((x) + 7) / 8 ) * 8)//-- 例10.将一个字母转换为大写
#define UPCASE(c) (((c)>='a'&&(c) <= 'z') ? ((c) - 0x20) : (c))//-- 例11.判断字符是不是10进值的数字
#define DECCHK(c) ((c) >= '0' && (c) <= '9')//-- 例12.判断字符是不是16进值的数字
#define HEXCHK(c) \(((c) >= '0' && (c) <= '9') || \((c) >= 'A' && (c) <= 'F') || \ ((c) >= 'a' && (c) <= 'f'))//-- 例13.防止溢出的一个方法
#define INC_SAT(val) (val = ((val)+1 > (val)) ? (val)+1 : (val))//-- 例14.返回数组元素的个数
#define ARR_SIZE(a) (sizeof((a)) / sizeof((a[0])))
相关文章:
活用C语言之宏定义应用大全
零、C语言宏定义知多少 C语言的编程过程中经常会用到宏定义,然而如果你只是使用宏定义做一些常量的定义,那么你不是OUT了就是C语言小白。 那么我们在编程过程中,宏定义都有哪些作用呢? 常量定义 可以作为功能代码的开关 防止头文件被重复…...
【源码】I.MX6ULL移植OpenCV
编译完成的源码: git clone https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.下载源码放在自己的opecv源码目录下 2.QTOpenCV工程代码放置的位置 3.更改.pro工程文件的opencv地址 4.使用命令行编译 前提是自己环境中已经配置好arm-qt的交叉编译…...
pytorch深度学习——dataset(附数据集下载)
在学习深度学习的时候,我们需要考虑如何去处理数据去训练我们的模型,pytorch为我们提供了Dataset和DataLoader两个类来对数据进行处理,前者作用是提供了一种方式来获取数据及其label,后者的作用是为网络提供不同的数据形式。本文主…...
springboot+vue考试管理系统
基于springboot和vue的考试管理系统 001 springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的在线考试管理系统,采用M(model)V(view)C(controller)三层体系结构&…...
自动驾驶建图--道路边缘生成方案探讨
自动驾驶建图–道路边缘生成方案探讨 一、背景 对于自动驾驶来说,建图是必不可少的,目前主流厂商技术都在从HD到"无图"进行过渡筹备中,不过想要最终实现真正的"无图"还是有很长的一段路要走。 对于建图来说,…...
图片编辑器中实现文件上传的三种方式和二进制流及文件头校验文件类型
背景 最近在 vue-design-editor 开源项目中实现 psd 等多种文件格式上传解析成模板过程中, 发现搞定设计文件上传没有使用 input 实现文件上传, 所以我研究了一下相关技术, 总结了以下三种文件上传方法 input 文件选择window.showOpenFilePicker 和 window.showDirectoryPicke…...
深度学习,CRNN+CTC和Attention OCR你更青睐哪一种?
深度学习在OCR领域的应用已经取得了瞩目的成果,而选择合适的算法对于提升OCR的识别准确率至关重要。在众多算法中,CRNN和Attention OCR犹如两颗璀璨的明珠,备受瞩目。 CRNN,这位结合了卷积神经网络(CNN)和…...
飞桨AI应用@riscv OpenKylin
在riscv编译安装飞桨PaddlePaddle参见: 算能RISC-V通用云编译飞桨paddlepaddleopenKylin留档_在riscv下进行paddlelite源码编译-CSDN博客 安装好飞桨,就可以用飞桨进行推理了。刚开始计划用ONNX推理,但是在算能云没有装上,所以最…...
在MongoDB建模1对N关系的基本方法
“我在 SQL 和规范化数据库方面拥有丰富的经验,但我只是 MongoDB 的初学者。如何建立一对 N 关系模型?” 这是我从参加 MongoDB 分享日活动的用户那里得到的最常见问题之一。 我对这个问题没有简短的答案,因为方法不只有一种,还有…...
C++基础之运算符重载(十一)
首先为什么要对运算符进行重载?因为C内置的运算符只能作用于一些基本数据类型,而对类和结构体这种自定义数据类型是不管用的。所以这时我们需要对运算符进行重新定义满足一定的运算规则。 运算符重载的三种形式 1.以普通的函数进行重载 #include <…...
初始Java篇(JavaSE基础语法)(2)(逻辑控制)
个人主页(找往期文章包括但不限于本期文章中不懂的知识点):我要学编程(ಥ_ಥ)-CSDN博客 目录 逻辑控制 顺序结构 分支结构 if语句 switch 语句 循环结构 while 循环 for 循环 do while 循环 输入输出 输出到控制台 从键盘输入 …...
家用路由器和企业路由器的区别?
一、家用路由器 家用路由器路由器交换机 它只有一个WAN口和一个LAN口,WAN口接公网一个地址,LAN口接你电脑一个IP地址,完全符合路由器的设计,而因为家里如果用了,说明要接多个电脑,那么如果还需要对每个接口…...
Gin简介(Go web基础知识)
Gin简介 https://geektutu.com/post/quick-go-gin.html我是从这个网站上面摘录的,就是做个笔记,仅分享。膜拜极客兔兔大佬 Go特性: 快速:路由不使用反射,基于Radix树,内存占用少。 中间件:HT…...
HBase的Bulk Load流程
目录 1. 数据准备 2. 文件移动 3. 加载数据 4. Region处理 5. 元数据更新 6. 完成加载 7. 清理 8. 异常处理 LoadIncrementalHFiles(也称为Bulk Load)是HBase中一种将大量数据高效导入到HBase表的机制。以下是LoadIncrementalHFiles的主要流程步…...
vue中图片替换 遇到问题
问题: 在img标签里动态绑定路径:<img v-bind:src"imgSrc" /> data里这样写是错误的:imgSrc:xx/xx.png 这样渲染的路径会有问题,导致出不来图片 解决了 是这样的 data(){return(){imgSrc:require("../…...
Android 观察者模式
在Android中,观察者模式(Observer Pattern)是一种常用的设计模式,用于在对象之间建立一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在Android开发中࿰…...
阿里云部署MySQL、Redis、RocketMQ、Nacos集群
文章目录 🔊博主介绍🥤本文内容MySQL集群配置云服务器选购CPU选择内存选择云盘选择ESSD AutoPL云盘块存储性能(ESSD) 镜像选择带宽选择密码配置注意事项 安装docker和docker-compose部署MySQL三主六从半同步集群一主二从同步集群规…...
day05-店铺营业状态设置
1. Redis入门 1.1 Redis简介 Redis 是一个基于内存的 key-value 结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网: https://redis.io 中文网: https://www.redis.net.cn/ 主要特点: 基于内存存储,读写性能高…...
哈希表(c++)
1、介绍 哈希表,也称为散列表,是一种非常高效的数据结构。它通过将键(Key)映射到数组的特定位置来快速查找、插入和删除数据。这个映射过程由哈希函数(Hash Function)完成,该函数将键转化为一个…...
C#基础-标识符命名规则
目录 1、标识符定义 2、遵循规则 3、标识符的例子 4、MSDN中英文解释 英文...
OpenClaw技能扩展实战:用百川2-13B自动化处理Excel数据
OpenClaw技能扩展实战:用百川2-13B自动化处理Excel数据 1. 为什么选择OpenClaw处理Excel数据 作为一个经常需要处理数据报表的技术博主,我过去每周都要花数小时手动整理Excel表格。从数据清洗到生成可视化图表,这些重复性工作不仅枯燥&…...
OpenClaw日志分析:百川2-13B-4bits模型自动化排查系统错误
OpenClaw日志分析:百川2-13B-4bits模型自动化排查系统错误 1. 为什么需要智能日志分析 每次系统半夜报错时,我都会被报警电话惊醒,然后手忙脚乱地登录服务器查日志。那些密密麻麻的报错信息就像天书,经常需要反复搜索、比对历史…...
终极Godot解包指南:3分钟学会提取游戏资源
终极Godot解包指南:3分钟学会提取游戏资源 【免费下载链接】godot-unpacker godot .pck unpacker 项目地址: https://gitcode.com/gh_mirrors/go/godot-unpacker 想要轻松提取Godot游戏中的图片、音频和脚本资源吗?godot-unpacker正是你需要的God…...
Path of Building:流放之路玩家的离线构建规划神器,5步打造完美角色
Path of Building:流放之路玩家的离线构建规划神器,5步打造完美角色 【免费下载链接】PathOfBuilding Offline build planner for Path of Exile. 项目地址: https://gitcode.com/GitHub_Trending/pa/PathOfBuilding Path of Building(…...
已登CVPR&Nature子刊,小波变换+深度学习杀疯了 !!
融合小波变换的深度学习模型是当前的研究热点之一,这个交叉领域热度高、前景好、创新空间大,只要选对结合点和方法,冲顶会顶刊问题不大。比如Transformer、GNN、KAN、CNN、mamba等,就是目前比较前沿而且热度很高的结合方式&#x…...
嵌入式开发中段错误的成因分析与GDB调试实战
1. 嵌入式软件段错误概述段错误(Segmentation Fault)是嵌入式开发中最令人头疼的运行时错误之一。作为一名在嵌入式领域摸爬滚打多年的工程师,我处理过的段错误案例不下百例。每次遇到这种错误,就像在漆黑的迷宫里寻找出口&#x…...
【DVWA实战】——Low级别SQL注入:从手工探测到自动化利用全解析
1. 环境准备与基础配置 第一次接触DVWA这个靶场时,我花了整整一个下午才把环境跑通。这里给新手朋友分享几个避坑要点:首先确保你的PHP版本在5.4到7.4之间(太高版本会报错),MySQL建议用5.x版本。安装完成后别急着操作&…...
暗黑破坏神II终极存档编辑指南:Diablo Edit2让你的角色随心所欲
暗黑破坏神II终极存档编辑指南:Diablo Edit2让你的角色随心所欲 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 还在为暗黑破坏神II中加点错误而烦恼吗?还在为刷不到心仪装…...
雀魂AI助手Akagi:革新麻将竞技的智能决策系统
雀魂AI助手Akagi:革新麻将竞技的智能决策系统 【免费下载链接】Akagi 支持雀魂、天鳳、麻雀一番街、天月麻將,能夠使用自定義的AI模型實時分析對局並給出建議,內建Mortal AI作為示例。 Supports Majsoul, Tenhou, Riichi City, Amatsuki, wit…...
UE5蓝图实战:用JsonLibrary插件轻松搞定WebUI数据交互(附完整节点图)
UE5蓝图实战:用JsonLibrary插件轻松搞定WebUI数据交互 在虚幻引擎5的蓝图开发中,WebUI插件为开发者提供了强大的网页交互能力。然而,当涉及到前后端数据交换时,JSON格式的处理往往成为新手开发者的绊脚石。本文将带你深入探索Json…...
