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

活用C语言之宏定义应用大全

零、C语言宏定义知多少

C语言的编程过程中经常会用到宏定义,然而如果你只是使用宏定义做一些常量的定义,那么你不是OUT了就是C语言小白。

那么我们在编程过程中,宏定义都有哪些作用呢?

  1. 常量定义

  2. 可以作为功能代码的开关

  3. 防止头文件被重复包含

  4. 定义一些通用类型,防止因为平台和编译器不同导致的类型差异,方便移植

  5. 其他高级浮夸用法

  6. 。。。。。。

下面,我们来罗列一下宏定义的各种使用方法,建议收藏。

一、常量定义

//定义π值,代码易读

#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语言的编程过程中经常会用到宏定义&#xff0c;然而如果你只是使用宏定义做一些常量的定义&#xff0c;那么你不是OUT了就是C语言小白。 那么我们在编程过程中&#xff0c;宏定义都有哪些作用呢? 常量定义 可以作为功能代码的开关 防止头文件被重复…...

【源码】I.MX6ULL移植OpenCV

编译完成的源码&#xff1a; git clone https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.下载源码放在自己的opecv源码目录下 2.QTOpenCV工程代码放置的位置 3.更改.pro工程文件的opencv地址 4.使用命令行编译 前提是自己环境中已经配置好arm-qt的交叉编译…...

pytorch深度学习——dataset(附数据集下载)

在学习深度学习的时候&#xff0c;我们需要考虑如何去处理数据去训练我们的模型&#xff0c;pytorch为我们提供了Dataset和DataLoader两个类来对数据进行处理&#xff0c;前者作用是提供了一种方式来获取数据及其label&#xff0c;后者的作用是为网络提供不同的数据形式。本文主…...

springboot+vue考试管理系统

基于springboot和vue的考试管理系统 001 springboot vue前后端分离项目 本文设计了一个基于Springbootvue的前后端分离的在线考试管理系统&#xff0c;采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…...

自动驾驶建图--道路边缘生成方案探讨

自动驾驶建图–道路边缘生成方案探讨 一、背景 对于自动驾驶来说&#xff0c;建图是必不可少的&#xff0c;目前主流厂商技术都在从HD到"无图"进行过渡筹备中&#xff0c;不过想要最终实现真正的"无图"还是有很长的一段路要走。 对于建图来说&#xff0c;…...

图片编辑器中实现文件上传的三种方式和二进制流及文件头校验文件类型

背景 最近在 vue-design-editor 开源项目中实现 psd 等多种文件格式上传解析成模板过程中, 发现搞定设计文件上传没有使用 input 实现文件上传, 所以我研究了一下相关技术, 总结了以下三种文件上传方法 input 文件选择window.showOpenFilePicker 和 window.showDirectoryPicke…...

深度学习,CRNN+CTC和Attention OCR你更青睐哪一种?

深度学习在OCR领域的应用已经取得了瞩目的成果&#xff0c;而选择合适的算法对于提升OCR的识别准确率至关重要。在众多算法中&#xff0c;CRNN和Attention OCR犹如两颗璀璨的明珠&#xff0c;备受瞩目。 CRNN&#xff0c;这位结合了卷积神经网络&#xff08;CNN&#xff09;和…...

飞桨AI应用@riscv OpenKylin

在riscv编译安装飞桨PaddlePaddle参见&#xff1a; 算能RISC-V通用云编译飞桨paddlepaddleopenKylin留档_在riscv下进行paddlelite源码编译-CSDN博客 安装好飞桨&#xff0c;就可以用飞桨进行推理了。刚开始计划用ONNX推理&#xff0c;但是在算能云没有装上&#xff0c;所以最…...

在MongoDB建模1对N关系的基本方法

“我在 SQL 和规范化数据库方面拥有丰富的经验&#xff0c;但我只是 MongoDB 的初学者。如何建立一对 N 关系模型&#xff1f;” 这是我从参加 MongoDB 分享日活动的用户那里得到的最常见问题之一。 我对这个问题没有简短的答案&#xff0c;因为方法不只有一种&#xff0c;还有…...

C++基础之运算符重载(十一)

首先为什么要对运算符进行重载&#xff1f;因为C内置的运算符只能作用于一些基本数据类型&#xff0c;而对类和结构体这种自定义数据类型是不管用的。所以这时我们需要对运算符进行重新定义满足一定的运算规则。 运算符重载的三种形式 1.以普通的函数进行重载 #include <…...

初始Java篇(JavaSE基础语法)(2)(逻辑控制)

个人主页&#xff08;找往期文章包括但不限于本期文章中不懂的知识点&#xff09;&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 目录 逻辑控制 顺序结构 分支结构 if语句 switch 语句 循环结构 while 循环 for 循环 do while 循环 输入输出 输出到控制台 从键盘输入 …...

家用路由器和企业路由器的区别?

一、家用路由器 家用路由器路由器交换机 它只有一个WAN口和一个LAN口&#xff0c;WAN口接公网一个地址&#xff0c;LAN口接你电脑一个IP地址&#xff0c;完全符合路由器的设计&#xff0c;而因为家里如果用了&#xff0c;说明要接多个电脑&#xff0c;那么如果还需要对每个接口…...

Gin简介(Go web基础知识)

Gin简介 https://geektutu.com/post/quick-go-gin.html我是从这个网站上面摘录的&#xff0c;就是做个笔记&#xff0c;仅分享。膜拜极客兔兔大佬 Go特性&#xff1a; 快速&#xff1a;路由不使用反射&#xff0c;基于Radix树&#xff0c;内存占用少。 中间件&#xff1a;HT…...

HBase的Bulk Load流程

目录 1. 数据准备 2. 文件移动 3. 加载数据 4. Region处理 5. 元数据更新 6. 完成加载 7. 清理 8. 异常处理 LoadIncrementalHFiles&#xff08;也称为Bulk Load&#xff09;是HBase中一种将大量数据高效导入到HBase表的机制。以下是LoadIncrementalHFiles的主要流程步…...

vue中图片替换 遇到问题

问题&#xff1a; 在img标签里动态绑定路径&#xff1a;<img v-bind:src"imgSrc" /> data里这样写是错误的&#xff1a;imgSrc:xx/xx.png 这样渲染的路径会有问题&#xff0c;导致出不来图片 解决了 是这样的 data(){return(){imgSrc:require("../…...

Android 观察者模式

在Android中&#xff0c;观察者模式&#xff08;Observer Pattern&#xff09;是一种常用的设计模式&#xff0c;用于在对象之间建立一对多的依赖关系&#xff0c;当一个对象的状态发生改变时&#xff0c;所有依赖于它的对象都会得到通知并自动更新。在Android开发中&#xff0…...

阿里云部署MySQL、Redis、RocketMQ、Nacos集群

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容MySQL集群配置云服务器选购CPU选择内存选择云盘选择ESSD AutoPL云盘块存储性能&#xff08;ESSD&#xff09; 镜像选择带宽选择密码配置注意事项 安装docker和docker-compose部署MySQL三主六从半同步集群一主二从同步集群规…...

day05-店铺营业状态设置

1. Redis入门 1.1 Redis简介 Redis 是一个基于内存的 key-value 结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件。 官网&#xff1a; https://redis.io 中文网&#xff1a; https://www.redis.net.cn/ 主要特点&#xff1a; 基于内存存储&#xff0c;读写性能高…...

哈希表(c++)

1、介绍 哈希表&#xff0c;也称为散列表&#xff0c;是一种非常高效的数据结构。它通过将键&#xff08;Key&#xff09;映射到数组的特定位置来快速查找、插入和删除数据。这个映射过程由哈希函数&#xff08;Hash Function&#xff09;完成&#xff0c;该函数将键转化为一个…...

C#基础-标识符命名规则

目录 1、标识符定义 2、遵循规则 3、标识符的例子 4、MSDN中英文解释 英文...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...