C语言:#define详解

2023-05-16

#define定义标识符

语法:
#define name stuff
tips:我们在define定义标识符的时候,不建议在后面加上 ;,这样很容易出问题。比如说在以下的情况中:
if ( condition )
max = MAX ;
else
max = 0 ;

 #define定义宏

#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义 宏(define macro)。

宏的申请方式:#define name( parament-list ) stuff

其中的 parament - list 是一个由逗号隔开的符号表,它们可能出现在 stuff 中。
如果我们要写 #define SQUARE( x ) x * x 这样的一个宏。
#define SQUARE(x) x*x //参数列表的左括号必须与name紧邻

int main()
{
    int r = 5;
    printf("%d\n", r);
    
    return 0;
}

打印出来的结果就是25。但是这样一个宏定义也存在着一定的问题。如果说我们传进去的值是5+1,那么它打印出来的结果会是11而不是36。

原因就在于5+1是替换掉宏定义中的x。就变成了int r = 5+1*5+1。只需要加上括号即可解决,#define SQUARE(x) ((x) * (x))。

 #define替换规则

                   在程序中扩展#define定义符号和宏时,需要涉及几个步骤。

1. 在调用宏时,首先对参数进行检查,看看是否包含任何由 #define 定义的符号。如果是,它们首先被替换。
2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
3. 最后,再次对结果文件进行扫描,看看它是否包含任何由 #define 定义的符号。如果是,就重复上述处理过程。

#和## 

 #可以把参数插入到字符串中

#define PRINT(N) printf("the value of "#N" is %d\n", N)

int main()
{
    int a = 10;
    PRINT(a);

    int b = 20;
    PRINT(b);

    return 0;
}

在N的前面加上#,N的参数不会替换成它本身,而是会转换成对应的字符。

##可以把位于他两边的符号合成一个符号

#define CAT(Class,Num) Class##Num

int main()
{
    int Class100 = 100;
    printf("%d\n",CAT(Class,100)

    return 0;
}

 这个例子表达的是,CAT有两个参数,##会把两个参数合成一个符号,所以打印的就是100。

带副作用的宏参数 

 当宏参数在宏的定义中出现超过一次的时候,如果参数带有副作用,那么你在使用这个宏的时候就可能 出现危险,导致不可预测的后果。副作用就是表达式求值的时候出现的永久性效果。

x + 1 ; // 不带副作用
x ++ ; // 带有副作用
#define MAX(a, b) ( (a) > (b) ? (a) : (b) )
...
x = 5;
y = 8; 
z = MAX(x++, y++);

printf("x=%d y=%d z=%d\n", x, y, z);

最终的结果是:x=6,y=10,z=9 

宏和函数对比 

#define 定义宏
函数
代码长度
每次使用时,宏代码都会被插入到程序中。除了非常
小的宏之外,程序的长度会大幅度增长
函数代码只出现于一个地方;每次使用这个函数时,都调用那个地方的同一份代码
执行速度
更快
存在函数的调用和返回的额外开
销,所以相对慢一些
操作符优
先级
宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果,所以建议宏在书写的时候多些括号。
函数参数只在函数调用的时候求值一次,它的结果值传递给函数。表达式的求值结果更容易预测。
带有
副作
用的
参数
参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果。
函数参数只在传参的时候求值一次,结果更容易控制。
参数
类型
宏的参数与类型无关,只要对参数的操作是合法的,它就可以使用于任何参数类型。
函数的参数是与类型有关的,如果参数的类型不同,就需要不同的函数,即使他们执行的任务是
不同的。
调试
宏是不方便调试的
函数是可以逐语句调试的
递归
宏是不能递归的
函数是可以递归

命名约定 

一般来讲函数的宏的使用语法很相似。所以语言本身没法帮我们区分二者。
那我们平时的一个习惯是:把宏名全部大写,函数名不要全大写

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言:#define详解 的相关文章

  • #ifndef.#define, #endif 的用法

    文件中的 ifndef define endif 很关键 xff0c 是为了避免多重包含 xff0c 比如如果两个C文件同时包含同一头文件 xff0c 那么就会出现问题 xff0c 所以使用这种方法可以有效避免这种情况 一般用法 xff1a
  • #define和const的区别

    这个区别用从几个角度来说 xff1a 角度1 xff1a 就定义常量说的话 xff1a const 定义的常数是变量 也带类型 xff0c define 定义的只是个常数 不带类型 角度2 xff1a 就起作用的阶段而言 xff1a def
  • C++中 #define的用法

    C 43 43 中 define的用法 转自 xff1a http www dingge com main article asp id 61 10 今天整理了一些 define的用法 xff0c 与大家共享 xff01 1 简单的defi
  • php中define()函数和defined…

    原文地址 xff1a php中define 函数和defined 函数的使用 及来防止恶意调用 作者 xff1a 疯子的博客 php中define 函数和defined 函数的使用 define 用来定义常量 xff0c 常量也是全局范围的
  • typedef和define有什么区别

    typedef和define都是替一个对象取一个别名 xff0c 以此增强程序的可读性 xff0c 区别如下 xff1a xff08 1 xff09 原理不同 define是C语言中定义的语法 xff0c 是预处理指令 xff0c 在预处理
  • dwm-1000 测距总是出现 #define SYS_STATUS_RXPTO 0x00200000UL /* Preamble detection timeout */

    ex 05b ds twr resp 程序 总是出现 致使官方的代码 无法实现通讯 define SYS STATUS RXPTO 0x00200000UL Preamble detection timeout 需要着重修改参数
  • C语言中define的用法

    define顾名思义 xff0c 就是下定义 xff0c 那么在C中它也发挥着下定义的作用 1 提前定义变量 include lt stdio h gt define N 100 int main int a 61 10 printf 34
  • c语言 gpio指针定义,#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)这句话的具体作用是什么啊...

    一 GPIO Init函数解析 1 1 参数GPIO TypeDef 1 2 参数GPIO InitStruct 2 3 函数代码详解 4 4 备注 6 一 GPIO Init函数解析 首先来看一下GPIO Init函数的原型void GP
  • #define、typedef 和 using之间的联系和区别

    目录 一 define 1 含义 2 用处 1 条件编译 2 解宏 3 文件包含 二 typedef 1 含义 2 用处 1 数据类型别名 2 指针别名 3 结构体别名 4 与平台无关的数据类型 三 using 1 含义 2 用处 1 权限
  • C语言带参#define个人理解

    之前接触带参 define比较少 xff0c 这几天 查阅stm32官方固件库 xff0c 看到以下代码有点懵 xff1a define IS GPIO ALL PERIPH PERIPH PERIPH 61 61 GPIOA PERIPH
  • C语言:#define详解

    define定义标识符 语法 xff1a define name stuff tips xff1a 我们在define定义标识符的时候 xff0c 不建议在后面加上 xff1b xff0c 这样很容易出问题 比如说在以下的情况中 xff1a
  • const与define的区别

    1 define是预编译指令 xff0c const是普通变量的定义 xff0c define定义的宏是在预处理阶段展开的 xff0c 而const定义的只读变量是在编译运行阶段使用的 2 const定义的是变量 xff0c 而define
  • 关于C++中的#define

    include lt iostream gt using namespace std define ADD x y x 43 y 试卷上是减号 xff0c 本人觉得是加号 int main int m 61 3 int n 61 4 m 4
  • C语言学习笔记->const和define区别

    1 define 是预编译指令 xff0c 而const 是普通变量的定义 define定义的宏是在预处理阶段展开的 xff0c 而const定义的只读变量在编译运行中使用 2 const定义的是变量 xff0c 而define定义的是常量
  • C语言--符号常量

    在C语言中 可以用一个标识符来表示一个常量 称之为符号常量 其特点是编译后写在代码区 不可寻址 不可更改 属于指令的一部分 一 符号常量定义用 define 符号常量在使用之前必须先定义 其一般形式为 形式为 define 标识符 常量 e
  • #define宏定义详解

    define宏定义 1 常规用法 无参宏 define PI 3 1415926 define EN 1e5 定义指数1 10e5 cout lt
  • define( )和defined( )函数的区别

    PHP中define 函数用来定义一个常量 而defined 函数用来检验常量是否存在 存在则返回true 否则返回false
  • require js之define 函数

    require js define 函数 模块不同于传统的脚本文件 它良好地定义了一个作用域来避免全局名称空间污染 它可以显式地列出其依赖关系 并以函数 定义此模块的那个函数 参数的形式将这些依赖进行注入 而无需引用全局变量 Require
  • C++预处理器

    预处理器是一些指令 指示编译器在实际编译之前所需完成的处理 define define用于定义宏 宏是一个代码级的文本替换 因为替换发生在编译之前 神奇的例子 来猜猜输出结果 define STR s s 会给 s 加上双引号 s defi
  • 21,verilog之宏define介绍

    注 学习 交流就在博主的个人weixin公众号 FPGA动力联盟 留言或直接 博主weixin fpga start 私信 宏define提供用一个相对简单的文字来表示一大段真正有意义的文字作用 换句话说 就是综合软件见到定义的宏 就用这个

随机推荐

  • Arduino基础与常用函数

    文章目录 1 Arduino语言2 Arduino代码结构1 类似于C的头文件包含 xff0c 变量定义等2 void setup 3 void loop 3 串口常用函数1 串口收发函数 Serial begin speed 2 读取串口
  • pixhawk px4 commander.cpp

    对于复杂的函数 xff0c 要做的就是看函数的输入是什么 来自哪里 xff0c 经过处理后得到什么 给谁用 xff0c 这样就可以把程序逻辑理清 中间的分析就是看函数如何处理的 span class hljs keyword extern
  • ESP8266 读取多个传感器数据(风速、风向、颗粒物、CO)

    文章目录 1 ESP8266开发板资源2 Arduino编程1 准备工作2 读取多个串口数据1 定义软串口 2 涉及传感器简介 3 集成代码 xff08 注释详细 xff09 4 Arduino 串口监视器 1 ESP8266开发板资源 一
  • ESP8266采集多个传感器数据通过WIFI上传到本地数据库(风速、风向、CO、颗粒物)

    文章目录 1 数据库使用简介1 Navicat premium连接2 新建数据库3 在数据库中新建表 2 代码实现代码 1 数据库使用简介 建立数据库连接 xff0c 在连接里新建数据库 xff0c 在数据库里新建表 1 Navicat p
  • STM32读取串口传感器(颗粒物传感器,被动传输)

    文章目录 1 串口2中断 xff08 在主动上传的基础上 xff09 1 添加发送字符和数组函数2 主函数调用3 串口助手接收数据 2 遇到的串口通信不成功问题 1 串口2中断 xff08 在主动上传的基础上 xff09 1 添加发送字符和
  • STM32采集问答式串口传感器数据写入SD卡(spi模式)

    文章目录 1 实验工具2 接线说明3 部分代码说明1 文件的覆盖问题1 文件系统的文件打开方式2 移动文件初始写入指针位置 2 变量的转换及写入问题1 sprintf函数2 CSV文件创建 3 数据采集流程 xff08 主函数 中断函数处理
  • (1)STM32 RC522模块测试代码

    文章目录 1 使用资源2 RC522模块2 1 RC522简介2 2 RC522工作模式 3 模块测试代码 工程文件源码链接 1 使用资源 使用32 的SPI1资源 xff1a SDA PA4 RST PA1 普通io SCK PA5 MI
  • (3)STM32 SG90舵机模块测试

    文章目录 1 资源简介2 测试源码 1 资源简介 stm32 rct6板SG90舵机模块 接线引脚 xff1a 橙色 xff1a 信号线 红色 xff1a 电源 43 5v 咖色 xff1a GND 此模块三条线固定在一起 xff0c 如果
  • (4) STM32 AS608指纹识别模块测试代码

    文章目录 1 使用资源2 实现思路简述3 指纹测试代码3 1 部分代码介绍3 2 源码链接 1 使用资源 stm32RCT6板子AS608指纹模块 软件资源 xff1a 串口二资源连接AS608 TX RX接线AS608 wak线连接PA8
  • 通过路由器连接JetsonNano与地面站

    通过路由器连接JetsonNano与地面站 一 前期准备注意事项连接局域网虚拟机网络设置 二 获取IP地址和设备名称IP地址设备名称 三 配置Nano修改bashrc文件修改hosts文件 四 配置地面站修改bashrc文件修改hosts文
  • jvm 堆 栈中存什么?

    数据类型 Java虚拟机中 xff0c 数据类型可以分为两类 xff1a 基本类型和引用类型 基本类型的变量保存原始值 xff0c 即 xff1a 他代表的 值就是数值本身 xff1b 而引用类型的变量保存引用值 引用值 代表了某个对象的引
  • YOLOv5 数据集划分及生成labels

    0 本人文件夹存放格式 xff08 因为要测试多个数据集和不同的yolov5版本和其他算法 xff0c 所以数据集整体放到外面 xff09 1 划分数据集 验证集 测试集 coding utf 8 import os import rand
  • mission planner发送数据之mavlink

    前段时间研究mp的地面站 xff0c 看了几天有点体会 xff0c 看网上的解析比较少 xff0c 写上来和大家分享下 xff0c 全是自己的理解 xff0c 东西比较少 xff0c 硬货不多 xff0c 还请见谅 最开始是想做个无人机超声
  • 实验三、嵌入式Linux网络通信实验

    实验三 嵌入式Linux网络通信实验 一 实验目的 1 掌握TCP与UDP协议原理 2 掌握套接字通信原理 2 掌握TCP套接字服务器端与客户端通信方法 二 实验基本要求 1 学习TCP与UDP协议原理 2 掌握TCP套接字服务器端与客户端
  • QT重载keyPress焦点问题

    最近项目上需要用到键盘上的快捷键 xff0c 就重载了键盘的按下事件 xff0c 以为万事大吉 实际界面上有很多控件 xff0c 导致如果鼠标点击了其中一个不能接收焦点的控件 xff0c 就不知道焦点传到了什么地方 上网查大致两种思路 xf
  • QT实现地图或图片的细节图(抓取图片的细节,放大图片)

    最近由于项目上的要求 xff0c 需要实现一个细节图 xff0c 就是一个矩形框中加载一个大图 xff0c 右下或者左下方有一个小矩形框 xff0c 可以加载全图 xff0c 并显示大矩形框中图片在全图的位置 xff0c 有点拗口 xff0
  • centos7 搭建vtk7.1.1+Qt开发环境+运行编译工程

    一 CMAKE安装 vtk必须用cmake编译 xff0c 但是 xff0c 由于高版本的cmake没有支持qt5的gui xff0c 所以选择低版本的 xff0c 但是低版本的必须得依赖于qt4 xff0c 而qt4相较于qt5 xff0
  • centos搭建vtk开发环境

    一 OpenGL3 0 vtk有个硬性要求就是OpenGL3 0及以上版本 xff0c 由于笔者此前使用的是centos7 xff0c 照着网上的教程配置OpenGL xff0c 但是之后glxinfo grep OpenGL发现openg
  • 读取ugrid格式文件

    include lt iostream gt include lt vector gt include lt string gt include lt fstream gt using namespace std int main int
  • C语言:#define详解

    define定义标识符 语法 xff1a define name stuff tips xff1a 我们在define定义标识符的时候 xff0c 不建议在后面加上 xff1b xff0c 这样很容易出问题 比如说在以下的情况中 xff1a