尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
#define和#、##、@#解析:
目录前言1.什么是预处理2.#define是什么一.关于#define:1.#define 的标识符定义2.#define 的函数定义3#define 的续行操作4#define 的常见作用a.方便维护b.方便程序员检测c.简化写法d.进行条件编译二.关于字符串常量化运算符 # 1.常见用法:2.对空格处理三.符号连接操作符符 ##四.单字符化操作符 # 注意事项前言1.什么是预处理C语言源文件要经过预处理、编译、链接才能生成可执行程序。预处理就是再编译前对源文件进行简单的加工处理。预处理主要是以 # 开头的命令例如 #includestdio.h #define 等。预处理命令要放在所有函数之外而且一般都放在源文件的前面。2.#define是什么#define 属于预处理器指令可以将一些常量或代码模块定义为宏在预处理是进行文本替换这个行为被称为宏替换或宏展开。一.关于#define:1.#define 的标识符定义定义标识符是 #define 最常见的用法也可以说是没有参数的宏定义。流程为#define ----- 标识符也叫宏名、宏 ------替换列表。示例#includestdio.h #define num 20 #define print printf int main() { print(%d, num); return 0; }运行结果如下图这里是一个简单的宏定义我们使用预处理指令 #define 定义了一个名为 print 和 num“printf” 和“num 在预处理阶段会被替换成函数 printf 和 20。2.#define 的函数定义简单来说就是 #define 的宏定义可以像函数一样接受参数。示例#includestdio.h #define add(x, y) ((x)(y)) #define max(x, y) ((x) (y) ?x:y) int main() { printf(%d\n, add(2, 3)); printf(%d\n, max(2, 3)); return 0; }运行结果如下图所示这里我们定义了两个名为 add max 的宏进行文本替换后分别求出参数之和和参数中最大值。3#define 的续行操作顾名思义就是将 #define 的替换列表放在二行及更多行上。示例#includestdio.h #define for(x) for(int i 0; i x; i)\ {\ printf(%2d,i);\ } int main() { for (5); return 0; }运行结果如下图由上我们可以知道#define 的多行定义关键是要在每一个换行的时候加上一个/。4#define 的常见作用a.方便维护示例#define size 100; int a[size];这里创建了一个数组当以后数组觉得数组太大或是太小我们可以通过改变宏定义的替换列表来一键改变数组 a 的大小。b.方便程序员检测当看别人的代码时或者回头观看以前的代码通常会忘记一个代码块代表的含义当使用如 add 等宏定义的函数时可以帮助我们快速理解。c.简化写法示例#define usi unsigned short int usi a;当我们需要经常使用 unsigned short int 时由于该类型较长经常会 觉得麻烦这时候就可以通过将其定义为 usi 并可以通过 usi 创建变量。d.进行条件编译示例#includestdio.h #define add 0 int main() { #ifdef add printf(1); #endif return 0; }运行结果如下如上图当 add 被定义时预处理指令 #ifdef 和 #endif 中的语句执行当讲 add 的宏定义注释掉时预处理指令中的语句不执行。二.关于字符串常量化运算符 # 1.常见用法:示例#includestdio.h #define print(a,b) printf(#a and %d,b) int main() { print(abc,3); return 0; }运行结果如下图所示由此我们可以知道在宏定义中当需要把一个宏的参数转换为字符串常量时则使用字符串常量化运算符#。在宏中使用的该运算符有一个特定的参数或参数列表。2.对空格处理示例#includestdio.h #define print(a,b) printf(#a and %d,b) int main() { print( a bc ,3); return 0; }运行结果如下图由此我们可以知道编译器会将子字符或者字子符串使用空格连接并丢弃字符或字符串两边的空格。三.符号连接操作符符 ##示例#includestdio.h #define num1 100 #define num(a) num##a int main() { printf(%d, num(1)); return 0; }运行结果如下图这里我们通过符号链接操作符 ## 将 num 和 1 连接成 num1 。注1.宏展开时 ## 两边的空格会自动去除。2.连接后的实际参数名必须为实际存在的参数名或是编译器已知的宏定义。3.如果##后的参数本身也是一个宏的话##会阻止这个宏的展开。四.单字符化操作符 # 用法与##类似。示例#includestdio.h #define fun(x) #x int main() { printf(%c, fun(a)); return 0; }运行结果如下所示这里通过 # 操作符将 a 转换成字符。注单字符化操作符# 最多有四个参数并只返回最后一个字符当参数超过四个时系统将报错。注意事项1.define是宏定义程序在预处理阶段将用define定义的内容进行了 替换 。因此在程序运行时常量表中并没有用define定义的常量系统不为它分配内存。2.define没有类型检查的功能因为它只进行文本替换。它只是简单地将宏调用替换为宏定义中指定的文本没有对文本进行语法分析和类型检查。这种情况下类型错误很容易发生特别是对于复杂的宏定义。3.define定义表达式时要注意“边缘效应”。示例#includestdio.h #define fun(a,b) ab int main() { printf(%d, fun(1, 2) * fun(3, 4)); return 0; }运行结果如下所示对于这个代码我们想得到的值为21 但是实际的值为11 。这是为什么我们将宏展开看看#includestdio.h int main() { printf(%d, 12*34); return 0; }这里本应该先和 1 相加的 2 却先与 3 相乘所以结果错误。我们可以通过多加括号来改变表达式运算顺序来预防“边缘效应”。4.define 宏定义后直到遇到 #undef 之前可以一直使用在 #undef 后先前的宏需要再次定义才能够使用。5.带副作用的宏参数示例#includestdio.h #define max(x,y) ((x)(y)?(x):(y)) int main() { int a 1, b 2; int c max(a, b); printf(%d, c); return 0; }这里宏展开后得到表达式 c ((a)(b)?(a):(b))这个式子的值与编译器有关就大大降低了代码的可移植性。
RELATED

相关推荐

NewsBlur 自托管部署与 MCP 智能体接入完整指南:从 Docker Compose 到 AI 阅读助手

NewsBlur 自托管部署与 MCP 智能体接入完整指南:从 Docker Compose 到 AI 阅读助手

后端前端社交人工智能 【免费下载链接】NewsBlur NewsBlur is a personal news reader that brings people together to talk about the world. A new sound of an old instrument. 项目地址: https://gitcode.com/gh_mirrors/ne/NewsBlur 点击查看 免费下载 本文基…

📅 2026/9/28 6:05:57
Markdown开发VSCode插件推荐:用TaoToken统一Key打通AI写作与预览链路

Markdown开发VSCode插件推荐:用TaoToken统一Key打通AI写作与预览链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/28 6:05:57
广州二手房价预测:数据清洗、特征工程与模型调参全解析

广州二手房价预测:数据清洗、特征工程与模型调参全解析

简介:这是一份面向数据分析学习者与房地产研究爱好者的广州市二手房价预测实践资源,包含广州市二手房交易数据集和完整的Python建模代码,围绕价格预测任务演示了从数据清洗、特征工程到模型训练评估的典型流程。压缩包共19个文件,…

📅 2026/9/28 6:00:57
MORE NEWS

更多资讯

📰

VisionTransformer图像去雾:Python源码与实战解析

简介:图像去雾是典型的病态反问题,传统方法依赖暗通道先验估计透射率,在天空、白墙等区域容易失效。VisionTransformer凭借全局自注意力机制,能够有效建模长程依赖,对不均匀雾和复杂场景表现出更强的稳定性。本文从大气…

📰

Midway @midwayjs/axios 组件演进与实战:从 HTTP 客户端组件诞生到 axios v1 的完整解析

后端微服务云原生 【免费下载链接】midway 🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate w…

📰

Mist 项目贡献指南:从 Bug 报告到 Pull Request 的协作规范与工程实践

区块链Web3桌面应用 【免费下载链接】mist [DEPRECATED] Mist. Browse and use apps on the Ethereum network. 项目地址: https://gitcode.com/gh_mirrors/mi/mist 点击查看 免费下载 本指南以 Mist(Ethereum Wallet)仓库的 CONTRIBUTING.m…

📰

Java宠物管理系统:数据库设计与JDBC实战全流程

简介:面向Java课程设计、毕业设计或综合实训场景,一份包含宠物管理系统完整开发流程的项目资料包,覆盖从环境配置、数据库设计到前后端联调与答辩展示的全过程。压缩包约136.77MB,内含源代码、数据库脚本、项目报告、答辩PPT、运行…

📰

YOLO卫星遥感目标检测实战:1825张标注图入门指南

简介:本资源是面向YOLO系列目标检测算法研究与工程实践的卫星遥感图像专用数据集,适用于高校遥感AI方向学生、计算机视觉初学者及工业级模型训练需求者,解决小目标、低分辨率遥感场景下通用数据集适配性差的问题。压缩包共2000个文件&#xf…

📰

STM32软件模拟IIC驱动TM1680数码管的精准时序实现

1. 项目概述:为什么非得“手把手”用软件模拟IIC驱动TM1680?STM32做数码管/LED点阵驱动时,很多人第一反应是找现成的IIC硬件外设——毕竟HAL库里HAL_I2C_Master_Transmit()一行调用就完事。但真到TM1680这种国产LED驱动芯片上,你会…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬