带参数的宏定义、函数与内联函数

2023-05-16

文章目录

  • 前言
  • 一、宏定义
    • 1.基本用法
    • 2.带参数的宏定义
  • 二、函数
    • 1.定义与声明
    • 2.调用
  • 三、内联函数--inline
  • 总结


前言

在实际项目开发,尤其是嵌入式软件项目中,经常可以看到大量宏定义的分布,其中又多以带参数的宏定义为主。对于刚入门的小白来说,这可能也算是C语言的高级用法之一。当然,它的用处也确实相当广泛。
带参数的宏,它的功能类似于函数。在多数场景当中,它的目的也是旨在能够一定程度上取代部分的函数调用。
以上两种方式并存,但各自都有优缺点,也因此,inline函数诞生。它可以说是兼具了函数和带参数的宏定义优缺点于一身的产物。


“存在即合理” --黑格尔《法哲学原理》

一、宏定义

1.基本用法

在预编译过程中无条件文本替换:

#include<stdio.h>

#define OKAY			0
#define OVERFLOW		1
#define UNDERFLOW		2
#define MAX				10
#define MIN				5

void main()
{
	unsigned char InputVal	= 0;
	unsigned char Result	= OKAY;

	printf("Inpue a new value please: ");
	scanf("%d", &InputVal);

	if( MAX < InputVal ){
		Result = OVERFLOW;
		printf("The input is OverFlow !\n");
	} else if( MIN > InputVal  ){
		Result = UNDERFLOW;
		printf("The input is UnderFlow !\n");
	}else{}
}

在预编译之后,文件中所有出现的宏定义,将分别被对应的数值替代,如,代码中出现MAX 的地方,被10取代,MIN被5取代。

2.带参数的宏定义

以下为一个经典的判断最值的例子:

#define MAX(a,b) ((a)>(b)?(a) : (b))

如果代码中有如下“调用”语句:

int c=MAX(5,3);

编译器预处理后,代码被替换为:

int c=((5)>(3)?(5) : (3));

不难看出,宏定义的使用,无论是否带有参数,其实就是一个纯粹的文本替换的过程。它的出现,在一定程度上,增强开发者或者后续维护者的交互体验,毕竟对于人类来说文字描述更容易理解。但是,它的劣势也是显而易见的:代码量的增加。毕竟再小规模的宏定义,替换的地方越多,也就意味着代码量的膨胀。
宏定义还有一个优势,即“一改全改”,不用查找文件中的所有引用逐一进行修改,只需要需改宏定义不分即可。当然,这也可能带来另一个致命的缺陷:一旦宏定义不准确,错误将是全局性的。

二、函数

1.定义与声明

int Func_Max(int a, int b)
{
	if(a > b)
		return a;
	return b;
} 

2.调用

int c=Func_Max(5,3);

不难看出,c的值为5,函数Func_Max同样能实现以上宏定义MAX的功能,只不过,实现的过程有一定差异:

  1. 首先,函数是通过其函数指针进行调用的,不会进行代码文本的替换,因此代码量不会有过多的冗余产生;
  2. 函数在执行之前,首先会对返回值和参数列表进行安全性检查,并在调用时为它们分配一定的堆栈空间进行参数的暂存。

三、内联函数–inline

像static、extern 等一样,inline是C++中的一个关键词,可用于修饰函数和C++中类的成员函数:

inline int Func_Max(int a, int b)`
  1. inline定义的内联函数,函数的代码被放入符号表中,在使用时直接进行替换(像宏一样展开),没有了调用时堆栈资源的开销,效率也很高。
  2. 很明显,类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。

总结

函数、宏定义各自都有着自己的独特性,在自己的应用场景下,有着举足轻重的作用,不能说不能替代,但是替代之前也需要再三思量。inline函数算是二者的子系,它囊括了函数和宏定义的几乎所有的特点,无论是优点还是缺点,它的使用看似常规,快捷,但也暗藏杀机。当然,如果数量掌握了其用法,就另当别论了。

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

带参数的宏定义、函数与内联函数 的相关文章

  • C++ 判断一个 int 型整数是否为 2 的 N 次方(幂次)

    判断一个整数是否为2的幂次方法有以下几种 xff1a 1 循环除2 这是最简单最好理解的方式 对于一个数如果是2的幂次 xff0c 则其肯定可以被2一直整除直到其值为1 所以可以通过一个while循环判断 xff1a void judge
  • Dijkstra算法图文详解

    Dijkstra算法算是贪心思想实现的 xff0c 首先把起点到所有点的距离存下来找个最短的 xff0c 然后松弛一次再找出最短的 xff0c 所谓的松弛操作就是 xff0c 遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近 xff
  • 需求中如何画用例图

    UML用例图 用例图主要用来图示化系统的主事件流程 xff0c 它主要用来描述客户的需求 xff0c 即用户希望系统具备的完成一定功能的动作 xff0c 通俗地理解用例就是软件的功能模块 xff0c 所以是设计系统分析阶段的起点 xff0c
  • 反光板导航SLAM(二)VEnus代码浅析

    上一章简单介绍了VEnus中几个主要函数的作用 xff0c 这里详细展开看一下每个函数的具体思路 xff0c 通过研究具体的代码我们可以简单了解VEnus中对于反光柱定位的具体流程 1 IntensityExtraction Extract
  • TEB算法详解(TebLocalPlannerROS::computeVelocityCommands(3))

    第一章主要分析了teb算法的准备条件 xff0c 包括获取当前位姿与速度 对全局路径的裁减以获取局部路径等以及局部地图的获取等 第二章主要讲述了在获取前置条件后 xff0c 如何根据前置条件进行位姿优化 xff0c teb的路径优化主要是调
  • TEB算法详解 参数详解

    teb算法的基本思路之前已经看完了 xff0c 今天主要看一下teb算法的参数配置文件 xff0c 分析一下每个配置参数的作用 xff1a teb的参数主要可以包含以下几个部分 xff1a 1 Trajectory Trajectory的参
  • ROS 如何用自己的电脑连接其他设备查看Rviz

    Rviz的使用在ROS开发中是很常见的东西 xff0c 有时候为了方便我们需要查看某台设备的一些数据 xff0c 但是又没有一些直观的连接工具例如向日葵之类的 这些工具是要基于屏幕的 xff0c 如果设备上没有屏幕是无法使用的 那在只有ss
  • 调试时正常,maven install 找不到符号

    找不到符号 很可能是引用的自己的库没有加载最新版 把所有库都clean gt install一下 或root项目下clean gt install
  • 【springboot】org.aspectj.lang.ProceedingJoinPoint获取返回类型、参数名称/值等

    1 参数值 span class token class name Object span span class token punctuation span span class token punctuation span args s
  • no opencv_java455 in java.library.path

    直接把 opencv build java x64下的文件opencv java455 dll复制到Java JDK安装的bin目录下就解决了这个问题
  • openssl pem 生成公钥和私钥及文件

    下载 xff1a http slproweb com products Win32OpenSSL html 首先得安装OpenSSL软件包openssl xff0c 安装了这个软件包之后 xff0c 我们可以做这些事情 xff1a o Cr
  • DebugDiag 2 收集Dump

    DebugDiag简介 Debug Diagnostic Tool DebugDiag 是微软提供的工具 xff0c 可以用来追踪windows平台下的程序崩溃 xff0c 卡死 xff0c 内存泄漏等一些疑难问题的原因 xff0c 按照问
  • Stream List 的排序

    1 list的正序 span class token class name List span span class token generics span class token punctuation lt span span clas
  • 嵌入式WebSocket的实现

    系统硬件采用STM32 43 DM9000AEP xff0c 具体实现步骤如下 xff0c 第一步建立TCP监听端口可以随意 xff0c 等待浏览器发出http请求 Chrome浏览器发出的请求 第二步建立握手 服务端需要解析最少4个头字段
  • spring boot 注册成 windows 服务

    1 windows系统下将 34 java jar 34 注册成 windows 服务 demo bat 64 echo off d span class token builtin class name cd span d span cl
  • Golang UI

    GUI库 Fyne 跨平台 xff0c 移动端 相对复杂 https github com fyne io fyne Walk 精于 windows https github com lxn walk
  • 解决golang编译提示dial tcp 172.217.160.113:443: connectex: A connection attempt failed

    废话不多说 xff0c 直接开讲 还多新手朋友在编译go的过程中是不是经常会遇到这样的报错 module Get https proxy golang org dial tcp 172 217 160 113 443 connectex A
  • 更新后报错

    更新后 xff0c 运行程序就报这个错 no required module provides package xxx go mod file not found in current directory or any parent dir
  • go: go.mod file not found in current directory or any parent directory; see ‘go help modules‘

    go go mod file not found in current directory or any parent directory see go help modules 此时还需要初始化Go moudle go mod init
  • vc++ 6.0bug C1853

    c documents and settingsstudent桌面musicplayermaindlg cpp 1 fatal error C1853 Debug MusicPlayer pch is not a precompiled h

随机推荐

  • 人工智能知识点汇总

    一 AI应用领域 AI目前主要的应用领域有3个方向 xff0c 包括 xff1a 计算机视觉 语音交互 自然语言处理 1 1 计算机视觉 xff08 CV xff09 计算机视觉是一门研究如何使机器 看 的科学 xff0c 就是指用摄影机和
  • Java17(291)之后 , 禁用了TLS1.1 , 使JDBC无法用SSL连接SqlServer怎么办,以下是解决办法

    修改java security文件 1 找到jre的java security文件 2 打开java security并搜索 jdk tls disabledAlgorithms 61 3 删掉TLSv1 TLSv1 1 4 保存 可以了
  • NumPy、Torch和Tensorflow 代码对比

    深度学习 在深入学习的基本单位上实施初级到高级操作 gt Excerpts 我习惯于为不同的问题创建新的深度学习架构 xff0c 但选择哪个框架 xff08 Keras Pytorch TensorFlow xff09 通常比较困难 由于其
  • 2023年 机器学习常用算法

    01 线性回归 线性回归 xff08 Linear Regression xff09 可能是最流行的机器学习算法 线性回归就是要找一条直线 xff0c 并且让这条直线尽可能地拟合散点图中的数据点 它试图通过将直线方程与该数据拟合来表示自变量
  • STM32上SPI+DMA实现大批量读取flash数据

    最近做项目需要使用SPI 43 DMA xff0c 为了做实验感受DMA传输数据块 xff0c 本人以SPI 43 DMA来读取flash中的数据 网上有很多例程是spi直接读取flash xff0c 无法提高性能 因为只是简单的实验SPI
  • stm32通用定时器1s延时实现LED闪烁

    stm32有很多定时器 xff0c 每种定时器的功能也不尽相同 xff0c 今天学习了如何用通用定时器实现1s延时 xff0c 使LED灯闪烁 xff0c 现总结如下 xff1a 步骤总结 xff1a 使能定时器时钟 gt 配置定时器结构体
  • JDK 中使用js调用java类、方法

    最近研究阅读这个APP 其主要功能就是通过一个个书源 从而实现移动端阅读的体验 比如说某些在线小说阅读网站 会加上相应的广告 从而影响用户阅读体验 于是阅读这个APP就是做了类似净化阅读体验 但是小说阅读网站千千万万 如果去适配每个小说阅读
  • Spring项目在tomcat启动时调用action

    1 实现ServletContextListener接口 添加 64 WebListener注解 2 按照示例写代码 xff1a 第一个是开启时 xff0c 第二个是销毁时
  • ubuntu16.04安装opencv3.4

    参考blog https blog csdn net u013066730 article details 79411767 直接进行 完全没问题 sudo apt get install build essential libgtk2 0
  • 使用switch-case语句输出成绩等级

    问题描述 xff1a 输入一个0 100范围内发分数 xff0c 在不同的等级范围内输出不同的值 xff0c 要求使用switch case控制 0 60 等级为E 60 70 等级为D 70 80 等级为C 80 90 等级为B 90 1
  • 输出图案(六)---输出空心矩形

    输入矩形的宽 xff0c 高 xff0c 输出该空心矩形 xff0c 用 来进行表示 参考代码1 xff1a span class hljs comment include lt stdio h gt span span class hlj
  • C语言中交换两个数的方法

    问题描述 xff1a 程序中有两个数a b 其中a 61 4 b 61 5 xff0c 现在希望交换两个数的值 xff0c 使得a 61 5 b 61 4 在这里我总结了一下目前我已经掌握的C语言中交换两个数的方法 xff0c 主要如下几种
  • 输出平行四边形图案(多种方案)

    问题描述 xff1a 使用 在控制台打印平行四边形 例如 xff1a 平行四边形中最长的一行输出的 是5个 xff0c 则平行四边为 xff1a span class hljs bullet span span class hljs emp
  • 自己实现strcat函数

    问题描述 xff1a 自己实现一个MyStrcat函数 xff0c 要和C语言库函数的strcat函数完成同样的功能 问题分析 xff1a 首先我们要了解一下strcat函数它到底做了什么事情 1 函数原型 char strcat char
  • 简易文件打包程序

    对指定目录下面的文件进行打包 简易解包程序参考博客另外一篇文章 xff1a http blog csdn net yi ming he article details 77689453 打包方式 xff1a 把目录下面的文件名 xff0c
  • 简易解包程序

    对压缩包进行解压 简易压缩程序请参考博客的另外一篇文章 xff1a http blog csdn net yi ming he article details 77689405 解包方式 xff1a 根据打包建立的索引表 xff0c 找到对
  • linux 挂载错误Transport endpoint is not connected

    mount了mfs后 xff0c 重新挂载之后 xff0c 出现如下错误 xff1a usr local mfs bin mfsmount H 192 168 103 101 mnt fuse bad mount point 96 mnt
  • 新字体的永久注册

    CString GetCurrentModuleDir TCHAR szPath MAX PATH 43 1 61 0 if 0 61 61 GetModuleFileName HMODULE amp ImageBase szPath MA
  • yolov5/v7/v8自动检测多个文件夹及截取锚框

    目前yolo仅支持检测图片或单个文件夹 xff0c 但在很多时候需要对成百上千个文件夹中图片进行检测 xff0c 再根据得到的位置信息txt文件来截取图片 xff0c 如何一步完成呢 xff0c 详情见下文 在detect py中将save
  • 带参数的宏定义、函数与内联函数

    文章目录 前言一 宏定义1 基本用法2 带参数的宏定义 二 函数1 定义与声明2 调用 三 内联函数 inline总结 前言 在实际项目开发 xff0c 尤其是嵌入式软件项目中 xff0c 经常可以看到大量宏定义的分布 xff0c 其中又多