C语言练习百题之宏#define命令
宏(Macro)是C语言中的一种预处理指令,它使用#define命令定义符号常量、宏函数和代码片段。下面列举了各种宏的应用场景以及相关注意事项:
-
定义常量:
#define PI 3.14159265- 注意事项:使用宏定义常量可以提高代码的可读性,但要确保不会与其他定义冲突,并使用大写字母表示。
-
宏函数:
#define SQUARE(x) ((x) * (x))- 注意事项:宏函数通常用于简单的替换操作,但要小心参数的求值次数和副作用。最好用括号包围参数以防止预期外的行为。
-
条件编译:
#define DEBUG 1 #if DEBUG// Debug-specific code #endif- 注意事项:宏常用于条件编译,以在不同的编译配置下启用或禁用代码块。
-
字符串拼接:
#define CONCAT(a, b) a ## b- 注意事项:
##运算符用于将标识符拼接在一起,但要确保它们可以正确连接。
- 注意事项:
-
变参宏:
#define PRINTF(format, ...) printf(format, ##__VA_ARGS__)- 注意事项:变参宏允许函数接受可变数量的参数,但要小心参数的数量和类型,以及在调用时使用合适的格式控制。
-
条件宏定义:
#ifndef MY_MACRO #define MY_MACRO #endif- 注意事项:条件宏定义用于避免多次包含头文件,确保头文件只被包含一次。
-
宏嵌套:
#define MAX(a, b) ((a) > (b) ? (a) : (b)) #define SQUARE_MAX(x, y) SQUARE(MAX(x, y))- 注意事项:宏可以嵌套,但要确保嵌套不会导致不必要的复杂性。
-
位操作宏:
#define SET_BIT(reg, bit) ((reg) |= (1 << (bit))) #define CLEAR_BIT(reg, bit) ((reg) &= ~(1 << (bit)))- 注意事项:位操作宏用于设置和清除位,但要小心位偏移和数据类型。
-
代码片段:
#define BEGIN { #define END }- 注意事项:宏可以用于定义代码片段,但要小心代码的可读性和维护性。
-
宏的作用域:
- 注意事项:宏的作用域通常在定义它的文件中,不会跨越不同的源文件。
总之,宏是C语言中非常强大的工具,但也需要小心使用。要确保宏的命名规范、参数传递方式以及嵌套等方面是合理的,以避免不必要的错误和混淆。此外,宏定义的可维护性和可读性是很重要的,因此要保持它们的简洁性和清晰性。
当涉及更复杂的宏的应用场景时,你可以考虑以下情况:
- 泛型编程:使用宏实现泛型数据结构或算法。例如,你可以使用宏定义通用的数据结构,如通用队列或通用哈希表,以便在不同的项目中重复使用。
#define DEFINE_QUEUE(type) \
struct type##_queue { \type *buffer; \int size; \int front; \int rear; \
};DEFINE_QUEUE(int)
DEFINE_QUEUE(char)
- 日志记录:使用宏来实现灵活的日志记录,以便在不同的编译配置下调整详细程度或输出目标。
#define LOG_DEBUG(msg, ...) fprintf(stderr, "DEBUG: " msg "\n", ##__VA_ARGS__)
#define LOG_ERROR(msg, ...) fprintf(stderr, "ERROR: " msg "\n", ##__VA_ARGS__)
- 编码宏:编写宏来自动生成重复的代码或数据结构。例如,你可以编写一个宏,根据数据结构的描述来生成序列化和反序列化函数。
#define SERIALIZE(type, field) \
void serialize_##type(type data, FILE *file) { \fwrite(&data.field, sizeof(data.field), 1, file); \
}SERIALIZE(Person, age)
SERIALIZE(Person, name)
- 断言宏:创建自定义的断言宏,以提供更丰富的错误信息和跟踪。
#define CUSTOM_ASSERT(condition, message) \
do { \if (!(condition)) { \fprintf(stderr, "Assertion failed: %s, File: %s, Line: %d\n", message, __FILE__, __LINE__); \exit(1); \} \
} while (0)
- 日志级别控制:使用宏来控制日志记录的级别,以便根据需要启用或禁用不同级别的日志。
#define LOG(level, msg, ...) \
if (level <= LOG_LEVEL) { \fprintf(stderr, msg, ##__VA_ARGS__); \
}#define LOG_LEVEL 2
- 单元测试框架:创建自己的单元测试框架,使用宏来定义测试用例和断言。
#define TEST_CASE(name) \
void test_##name()#define ASSERT(condition) \
do { \if (!(condition)) { \fprintf(stderr, "Assertion failed: %s, File: %s, Line: %d\n", #condition, __FILE__, __LINE__); \exit(1); \} \
} while (0)
这些是更复杂的宏应用场景示例,它们可以提高代码的可维护性、复用性和灵活性,但也需要小心维护和调试,以确保其正确性。不正确的宏使用可能导致代码难以理解和维护。
相关文章:
C语言练习百题之宏#define命令
宏(Macro)是C语言中的一种预处理指令,它使用#define命令定义符号常量、宏函数和代码片段。下面列举了各种宏的应用场景以及相关注意事项: 定义常量: #define PI 3.14159265注意事项:使用宏定义常量可以提高…...
阿里云存储I/O性能、IOPS和吞吐量是什么意思?
云盘的存储I/O性能是什么?存储I/O性能又称存储读写性能,指不同阿里云服务器ECS实例规格挂载云盘时,可以达到的性能表现,包括IOPS和吞吐量。阿里云百科网aliyunbaike.com分享阿里云服务器云盘(系统盘或数据盘࿰…...
Linux知识点 -- 网络基础 -- 数据链路层
Linux知识点 – 网络基础 – 数据链路层 文章目录 Linux知识点 -- 网络基础 -- 数据链路层一、数据链路层1.以太网2.以太网帧格式3.重谈局域网原理4.MAC地址5.MTU6.查看硬件地址和MTU的命令7.ARP协议 二、其他重要协议或技术1.DNS(Domain Name System)2.…...
git服务器宕机后,怎么用本地仓库重新建立gitlab服务器(包括所有历史版本)
一、重新建立 当您的 GitLab 服务器因为某种原因宕机后,您可以使用本地仓库中的备份数据来恢复 GitLab 服务器。以下是一般的步骤,用于重新建立 GitLab 服务器: 注意: 这些步骤假定您已经定期备份了 GitLab 数据,包括…...
华为云云耀云服务器L实例评测 | 实例使用教学之综合导览
华为云云耀云服务器L实例评测 | 实例使用教学之综合导览 实例使用教学实例场景体验实例性能评测实例评测使用介绍华为云云耀云服务器 华为云云耀云服务器 (目前已经全新升级为 华为云云耀云服务器L实例) 华为云云耀云服务器是什么华为云云耀云…...
Elasticsearch 高级查询用法
ES(Elasticsearch)查询语法是用于搜索和检索文档的强大工具,它支持多种查询类型和选项。以下是一些常见的查询语法示例: 1. **Match查询**:使用match查询可以执行全文本搜索。 { "query": { …...
网络架构介绍
1 网络 7 层架构 7 层模型主要包括: 1. 物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传输比特流(就是由 1、0 转化为电流强弱来进行传输,到达目的地后在转化为1、0…...
第53节——Redux Toolkit初识
一、什么是Redux Toolkit 1、概念 Redux Toolkit是一个官方支持的、用于简化Redux开发的工具集。它提供了一些简单易用的API和工具,可以帮助开发者更快速、更高效地编写Redux应用。 2、主要功能 简化Redux的配置 Redux Toolkit提供了一个createSlice函数&#…...
AndroidStudio报错:Plugin with id ‘kotlin-android‘ not found.
第一步 要在自己的项目的build.gradle的buildscript中添加ext.kotlin_version 1.3.72 第二步 然后在dependencies里添加classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 大体如下: buildscript {ext.kotlin_version 1.3.72r…...
【ADB】借助ADB模拟滑动屏幕,并进行循环
使用adb shell input 的swipe函数(应该是个函数) swipe x1 y1 x2 y2 time(以毫秒为单位) adb shell input swipe 1070 2200 1070 200 10000 进行循环 adb shell "for i in $(seq 1 10); do input swipe 1070 2200 1070 2…...
BN体系理解——类封装复现
from pathlib import Path from typing import Optionalimport torch import torch.nn as nn from torch import Tensorclass BN(nn.Module):def __init__(self,num_features,momentum0.1,eps1e-8):##num_features是通道数"""初始化方法:param num_features:特征…...
请求和响应的概述
请求:在浏览器地址栏输入地址,点击回车请求服务器,这个过程就是一个请求过程。 响应:服务器根据浏览器发送的请求,返回数据到浏览器在网页上进行显示,这个过程就称之为响应。 针对Servlet的每次请求&…...
(深度学习快速入门)A Gentle Introduction to Graph Neural Networks 笔记
博客链接沐神讲解视频文章目录 一:什么是图二:常见数据如何表示为图(1)图像(2)文本(3)Real WorldA:分子B:社交网络C:论文引用D:其他三:图涉及的任务(1)图级别任务(2)节点级别任务(3)边级别任务四:使用图数据的挑战...
VIM指令
vim的工作模式 vim一般有6种工作模式。 普通模式:使用vim打开一个文件时默认模式,也叫命令模式,允许用户通过各种命令浏览代码、滚屏等操作。 插入模式:也可以叫做编辑模式,在普通模式下敲击 i 、a 或 o 就进入插入模…...
Android 10.0 framework层实现app默认全屏显示
1.前言 在10.0的系统开发中,在对于第三方app全屏显示的功能需求开发中,需要默认app全屏显示,针对这一个要求,就需要在系统启动app 的过程中,在绘制app阶段就设置全屏属性,接下来就实现这个功能 效果图如下: 2.framework层实现app默认全屏显示的核心类 frameworks\base\…...
【计算机网络黑皮书】传输层
【事先声明】 这是对于中科大的计算机网络的网课的学习笔记,感谢郑烇老师的无偿分享 书籍是《计算机网络(自顶向下方法 第6版)》 需要的可以私信我,无偿分享,课程简介下也有 课程链接 目录 传输服务与协议网络层与传输…...
轻量限制流量?阿里云轻量应用服务器月流量包收费说明
阿里云轻量应用服务器部分套餐限制月流量,轻量应用服务器按照套餐售卖,有的套餐限制月流量,有的不限制流量。像阿里云轻量2核2G3M带宽轻量服务器一年108元和轻量2核4G4M带宽一年297.98元12个月,这两款是不限制月流量的。阿里云百科…...
Linux手记
常用的配置文件 文件作用/etc/profile系统级别的shell配置文件,它包含了系统中所有用户的默认环境变量和系统级别的全局配置信息/etc/apt/apt.conf配置APT(Advanced Package Tool)软件包管理器的行为,包括代理等/etc/apt/sources…...
springboot配置
一、配置文件的加载顺序 SpringApplication从以下位置的application.properties文件加载属性,并将它们添加到Spring Environment中去,优先级如下: 当前目录的/config子目录(src\config)当前目录(跟src目录…...
大数据中的一些词汇解释
OLTP(online Transaction Prrocessing) OLTP是一个处理面向事务的数据的软件系统。术语“在线交易”是指实时完成活动,而不是批处理。此数据是结构化数据的常见来源,可作为许多分析过程的输入。OLTP交易讲究实时性,就…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版分享
平时用 iPhone 的时候,难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵,或者买了二手 iPhone 却被原来的 iCloud 账号锁住,这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
