【C语言】宏定义

news2024/11/23 4:58:55
  • 🚩 WRITE IN FRONT🚩   

  • 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四"🔎
  • 🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评百大博主、华为云享专家、阿里云专家博主、掘金优秀创作者、全网粉丝量6w+、全网访问量100w+🏅
  • 🆔 本文章内容由 謓泽 原创 如需相关转载请提前告知博主 ⚠
  • 📝 个人主页:謓泽的博客📃
  • 📣 专栏系列:【C】系列 📃
  • 🧑‍💻 Gitee:謓泽 (wsxsx) - Gitee.com⭐️
  • 🎁 点赞👍+ 收藏⭐️+ 留言📝​

目录

🍑宏定义不带参数

🍈优点

🍑定义宏 

🍈说明

🍈命名事项

🍻字符串宏常量

🍈practice[练习]

🍻#undef


🍑宏定义不带参数

        说明:宏定义指令的 #define 用来定义一个标识符和一个字符串,我们可以以这个标识符来表示这个字符串,在程序当中每次遇到该标识符的时候就用来所定义的字符串来进行替换它。宏定义的作用相当于给指定的字符串起了一个别名。

不带参数的宏的定义方式如下(这也是我们经常用到的宏定义)

#define 宏名 字符串 //没有分号,说没有分号倒不如说最好不要加分号

        这里说下原因吧:因为宏定义它并不是C语言的语句,所以不用加分号。 

  • 表示这是一条预处理命令。
  • 宏名实际上就是一个标识符,必须要符合C语言当中标识符的语法规定的。

        标识符的规则:字母、数字、下划线,不以数字开头,注意:关键字不能作为标识符!预定义标识符有define、printf、scanf 它们是可以作为标识符的。

  • 字符可以是常数、表达式 以及 格式字符串符等。
#define Num 1000

        说明:上述代码的作用就是该程序中用Mum来替代1000,在编译预处理的时候,每当代码在源程序中遇到Mum就自动的用1000来进行代替。

        注意:宏名要简单且定义的明确,一般习惯会用大写字母来去表示,来区分和变量的区别。

🍈优点

  1. 方便程序的修改,不用对整个程序进行修改,只需对宏定义上进行修改。
  2. 提高程序的运行效率,更加方便模块化。

🍑定义宏 

        #define 机制包括了一个规则,允许把参数替换到文本当中去,这种实现操作通常被称之为是宏(macro) 或者是 定义宏(define macro)

        带参数的宏定义方式如下格式↓

#define 宏名(参数表)字符串

        那么光说是不行的,我们就用宏定义来实现两个数字的相加。代码示例如下👇

#define _CRT_SECURE_NO_WARNINGS 1
#define ADD(x,y) x+y
#include<stdio.h>
int main(void)
{
	printf("相加的值:%d\n",ADD(5, 5));
	return 0;
}

运行结果🖊 

        相加的值:10

        上述代码的意思是我们先调用宏也就是宏调用,把宏里面的值传递给宏名当中的参数表,然后再传过去的参数表替换到字符串的文本当中去。

注意:宏的参数是先完成替换的,不是先计算然后再进行传参的。如下代码所示↓

#define _CRT_SECURE_NO_WARNINGS 1
#define S(x) x*x
#include<stdio.h>
int main(void)
{
	printf("相加的值:%d\n",S(3+1));
	return 0;
}

        我一开始的时候看到这个代码以为是16,4*4不就是16吗。实际上我想错了。

        它的工作原理是这个样子的,这里3+1就是宏的参数,那么就会把3+1传递到宏的参数当中去。那么这个时候替换完成之后就是:3+1 * 3+1,这不就是7吗。没错(@^0^)

        一句话总结:参数会经过任何的计算直接传入进去。 

        实际上我们想要得到4*4的一个结果实际上这也很容易,把字符串文本修改下即可。

#define S(x) (x)*(x)

        当然这还是不够严谨,完美再加一个小括号再外面。

#define S(x) ((x)*(x))

        ()YYDS!那么这个概念性的东西就说到这里,具体还是要多上手打下代码去进行实践。 

        那么接下来我们再举出一个例子,看大家能不能做对。(╹ڡ╹ )

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define M(x) (x)+(x)
int main(void)
{
	printf("%d ", 10 * M(2));
	return 0;
}

        🍎注意⇢上述这两个代码是不一样的仔细看看哟😛

​#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define M(x) (x)+(x)
int main(void)
{
	int a = 2;
	printf("%d ", 10 * M(a));
	return 0;
}

        注意⇢上述这两个代码是等价的,变量也是可以传入到参数表当中去的。

选出上述代码正确的值不能 一共四个选项如下↓

A:40

B:22

C:88

D:10

        可能有些人会选择A这个选项,因为 10 * 2 = 20 然后,20+20 = 40,但实际上这是错误的和上面所犯的错误都是一模一样的。

printf("%d",10 * (2) + (2));

        原型如上代码所示↑

        那我们想要得到 40 的值就必须要加小括号。如下形式↓

#define M(x) ((x)+(x))

        其实这也无非就是操作符的优先级大小,切记(✿◕‿◕✿) 

🍈说明

        宏参数和#define的定义中可以出现其他的#define定义的变量。但是对于宏,是不能出现递归的。

        当预处理搜索#define定义的符号的时候,字符串常量的内容并不被搜索。

在使用函数的时候我们需要注意它的数据类型,但是在宏当中我们是不需要注意的,想是整形就是整形想是浮点型就是浮点型。说明用宏在这里是更加灵活的只是处理简单问题上切记。

🍈命名事项

        相信有些小伙伴已经发现了这个函数的宏的使用语法和函数是非常类似滴。所以语言本身就会没办法帮我们区分二者的一些使用。那么我们平时写宏或者函数的时候的习惯是↓

  • 宏明全部大写形式。
  • 函数明不要全部大写,建议第一个字母大写。

🍻字符串宏常量

#include<stdio.h>
#define Name chenze
int main(void)
{
	printf("%s",Name);
    return 0;
}

(error)字符串没有带双引号编译器会直接报错✘

(correvt)正确写法是要在宏字符串带上双引号

#define Name "chenze"

        小知识点⇢宏是可以用来充当注释的效果的这个我在接触宏的时候我都没有想到这个问题,那么现在我们用BSC充当C++的风格注释。大家可以尝试去试一下这里我就不再演示了(@^0^)

🍈practice[练习]

        那么经过上述的知识点相信各位已经熟悉的差不多了接下来我们来做一道题目来练习practice以下吧。

        题目内容⇢用宏实现整形变量(a)和整形变量(b)把原来的值用宏实现清0并且打印原来(a,b)没有被宏清0之前的值。示例代码如下👇

#include<stdio.h>
#define empty0(a,b) a = 0;b = 0;
int main(void)
{
	int a = 20;
	int b = 10;
	printf("before:%d  %d\n", a, b);
	empty0(a, b);
	printf("after :%d  %d\n", a, b);
    return 0;
}

运行结果🖊

before:20  10

after   :0    0

✔说明⇢上述结果当中我们可以知道变量(a)和变量(b)通过宏被修改成为了0的值。

✔拓展⇢用do...while(0)语句结构可以在宏插入多条语句的结构因为有花括号{}在。

🍻#undef

#undef 是为取消定义,用于移除一个宏的定义。

格式形式如下

#undef NAME

如果现在的一共名字需要被重新定义的话,那么旧名字就会被移除。

🍏如下代码所示

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#define NUM 10
int main(void)
{
#undef NUM
	printf("num of:%d\n",NUM);
}

运行结果⇥error(错误)

        说明⇢上述代码原本是要打印NUM宏定义的值的,但是由于我们使用了#undef取消宏定义了。此时编译器就相当于未定义标识符NUM了说的简单点相当于不存在了,注:是在取消宏定义之后的语句当中的。

🍎拓展知识点⇥宏可以在任意地方使用。

#include<stdio.h>
int main(void)
{
	printf("num of 1:%d\n", 10);
#define M 20
	printf("num of 2:%d\n", M);
    return 0;
}

运行结果🖊

num of 1:10
num of 2:20

        🍏说明⇢在上述代码当中可以证明宏在源文件的任何地方宏都可以定义。宏的作用范围:从定义出开始往后它都是有效的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1057560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RFID藏品管理系统-智慧文物仓库管理系统

一、项目背景 RFID藏品管理系统DW-S407是一套成熟系统&#xff0c;依托互3D技术、云计算、大数据、RFID技术、智能传感器、AI、视频分析技术对文物仓库进行统一管理、分析的信息化、智能化、规范化的系统。 不管是博物馆还是艺术馆&#xff0c;藏品的管理都是非常复杂的。特…

使用Docker部署ElasticSearch7+ELK(附带ES操作操作命令集)

ElasticSearch 7ELK 程序安装Docker安装下载ES镜像提前创建挂载文件夹添加配置文件创建并启动容器可能出现的异常安装IK分词使用ElasticHD客户端工具(目前使用发现无法做增删改)安装Kibana 软件包安装安装ElasticSearch&#xff08;需要JDK1.8&#xff09;安装IK&#xff08;下…

【高阶数据结构】哈希(哈希表、哈希桶)

⭐博客主页&#xff1a;️CS semi主页 ⭐欢迎关注&#xff1a;点赞收藏留言 ⭐系列专栏&#xff1a;C进阶 ⭐代码仓库&#xff1a;C进阶 家人们更新不易&#xff0c;你们的点赞和关注对我而言十分重要&#xff0c;友友们麻烦多多点赞&#xff0b;关注&#xff0c;你们的支持是我…

Codeforces Round 901 (Div. 2)

Problem - A - Codeforces 贪心 每次都先让b减到1&#xff0c;然后再去选择工具来增加时间 AC代码: #include<bits/stdc.h> #define endl \n #define int long long using namespace std; const int N110; int x[N]; int a,b,n; void solve() {cin>>a>>b…

【C语言】模拟实现strlen

strlen是非常常用的字符串函数 目录 介绍&#xff1a;模拟实现&#xff1a;计数器递归指针-指针 介绍&#xff1a; 我们可得这个函数是求在字符串开始与\0之间的字符串长度 代码示例&#xff1a; #include <stdio.h> int main() {const char* str1 "abcdef"…

神器 CodeWhisperer

这两天看到了好多关于 Amazon CodeWhisperer 针对个人用户终身免费使用的消息&#xff0c;便抽空简单来重点介绍下如何在 VS Code 这款 IDE 上安装和使用 CodeWhisperer。 亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视…

Linux——进程间通信——system V系列

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——进程间通信——system V系列 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;system V 版本进程间通信的机制。 目录 一.共享…

WebGPU 入门:绘制一个三角形

大家好&#xff0c;我是前端西瓜哥。 今天我们来入门 WebGPU&#xff0c;来写一个图形版本的 Hello World&#xff0c;即绘制一个三角形。 WebGPU 是什么&#xff1f; WebGPU 是一个正在开发中的潜在 Web 标准和 JavaScript API&#xff0c;目标是提供 “现代化的 3D 图形和计…

AutoCAD 产品设计:图形单位

本文讲解 AutoCAD 产品的图形单位功能产品设计&#xff0c;没有任何代码实现。 使用的 AutoCAD 为 2020 版本 图形单位是什么&#xff1f; 图形单位是用于设置 一些属性数据应该用什么格式显示 的命令&#xff0c;命令标识为 un&#xff08;units&#xff09;。 举个例子。 …

操作EXCEL计算3万条数据的NDVI并填入

Python操作EXCEL&#xff0c;计算3万条数据的NDVI并填入 问题描述 现在是有构建好了的查找表&#xff0c;不过构建了3万条数据&#xff0c;在excel中手动计算每行的NDVI值太麻烦了&#xff0c;也不会操作。 就试试python吧&#xff0c;毕竟python自动处理大型EXCEL数据很方便…

黑马头条项目环境搭建

注册中心网关配置 spring:cloud:gateway:globalcors:add-to-simple-url-handler-mapping: truecorsConfigurations:[/**]:allowedHeaders: "*"allowedOrigins: "*"allowedMethods:- GET- POST- DELETE- PUT- OPTIONroutes:# 平台管理- id: useruri: lb://…

51单片机可调幅度频率波形信号发生器( proteus仿真+程序+原理图+报告+讲解视频)

51单片机可调幅度频率信号发生器( proteus仿真程序原理图报告讲解视频&#xff09; 讲解视频1.主要功能&#xff1a;2.仿真3. 程序代码4. 原理图4. 设计报告5. 设计资料内容清单&&下载链接***[资料下载链接](https://docs.qq.com/doc/DS1daV1BKRXZMeE9u)*** 51单片机可…

数据结构——计数与归并非递归

排序算法 前言一、归并的非递归实现二、计数排序三、序算法复杂度及稳定性分析总结 前言 重要的事说三遍&#xff01; 学习&#xff01;学习&#xff01;学习&#xff01; 努力!努力!努力&#xff01; 一、归并的非递归实现 代码实现&#xff1a; void MergeSortNonR(int* a,…

3分钟在移动盘上安装Ubuntu系统和ROS2

目录 原视频准备烧录 一个usb移动固态硬盘可以干什么呢&#xff1f; 可以用移动盘解决电脑存储空间不足的问题&#xff0c;可以用移动盘存储数据&#xff0c;可以用移动盘装其他系统当做双系统来使用&#xff0c;可以在一个移动固态硬盘里装两个甚至更多的系统… 下面&#xf…

《C++ primer plus》精炼(OOP部分)——对象和类(8)

学习是一项持续的投资&#xff0c;永远不会白费——本杰明富兰克林 文章目录 第13章&#xff1a;类继承一个基类和派生类公有继承的逻辑关系&#xff1a;is-a多态公有继承 第13章&#xff1a;类继承 一个基类和派生类 从一个类派生出另一个类时&#xff0c;原始类称为基类&am…

SLAM简要介绍

过去二十年&#xff0c;计算机视觉和机器学习领域都取得了很多进步。这一切都归功于硬件的改进&#xff0c;这使得研究人员和工程师能够设计和训练更复杂和更准确的模型&#xff0c;同时以以前难以想象的规模处理和分析数据。随着硬件的这些改进&#xff0c;未知环境的映射已经…

基于Java的学校固定资产管理系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

vue 使用 创建二维数组响应数据 渲染 echarts图标

目前我遇到的情况就是用动态的二维数组数据渲染echarts图标&#xff0c;我们从后端收到的接口一般是个一维数组&#xff0c;需要手动构建并且保证响应式。接下来我做了个案例 一、案例总逻辑 1. 先创建一个vue项目 2. 添加 echarts依赖 3. 模拟数据请求&#xff0c;构建二维数组…

支付宝2023年收单外包服务机构评级启动,截止11月15日

9月22日消息&#xff0c;支付宝近日发布公告称&#xff0c;已启动2023年收单外包服务机构评级工作。支付宝表示&#xff0c;收单外包服务机构评级工作是金融监管部门规范引导收单外包服务市场的重要举措&#xff0c;其结果将会向社会公示&#xff0c;直接关系到外包机构的业务开…

QT 之数据库 QSqlQuery CURD 实战

零、参考文档 https://doc.qt.io/archives/qt-6.0/qsqldatabase.html 一、开发环境 Ubuntu 20.04 QT6.0 Microsoft SQL Server 2022 Developer Edition (64-bit) 先修改 /etc/odbc.ini 的数据源配置&#xff0c;指定连接数据库 vdb&#xff0c; sudo vim /etc/odbc.ini[mss…