【C/C++】宏函数与内联函数的区别

文章目录

  • 【C/C++】宏函数与内联函数的区别
    • 一、概念
    • 二、特性
    • 三、优缺点
      • 3.1 内联函数的优缺点?
      • 3.2 宏的优缺点?
    • 四、笔试题
      • 4.1 为什么要是用宏,宏有什么优缺点?
      • 4.2 宏函数与内联函数的区别?
      • 4.3 C++中被const修饰的变量已经是常量,具有宏替换属性
    • 五、总结

一、概念

  以inline修饰的函数就叫做内联函数,C++编译器在编译时会在调用内联函数时地方展开,没有函数压栈的开销,内联函数提升程序的运行效率。

  内联函数在调用时不是像一般函数那样要转去执行被调用函数的函数体,执行完成后在转回调用函数中,执行其后的语句;而是在调用处 用内联函数体 的代码来替换,以这样的方式节省函数调用的开销,提高运行效率。

#include<iostream>
using namespace std;
//内联函数
inline int Max(int a, int b)
{if (a < b)return b;return a;
}
int main()
{int i=1;int j=2;int max = Max(i, j);cout << "max=" << max << endl;return 0;
}

二、特性

  1. inline是一种以空间换时间的做法,省去调用函数的开销。使用内联函数可以节省运行时间,但却增加了目标程序的长度。所以代码很长或者有循环、递归的函数不适宜使用内联函数,就算用了编译器也会放弃内联方式,而采用像调用普通函数的方式去调用它。只有那些那些规模较小而又被频繁调用的简单函数,才适合定义为inline函数。

  2. 内联函数必须是和函数体声明在一起才有效。不建议将声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

inline ADD(int left,int right);
// 没有效果,编译器只是把函数作为普通的函数声明。所以必须定义函数体
inline ADD(int left,int right){ return left+right;}
// 这样才算是定义了一个内联函数。

  3. 可以将定义在类外的函数定义为内联函数

//类的内联函数
class Math
{public:int add(){return i + j;}inline int sub(){return i - j;}int GetNum();private:int i, j;
};inline int Math::GetNum()
{return i;
}
// 该类中声明了3个内联函数add、sub和GetNum,
//在C++中,在类的内部定义了函数体的函数,被默认为是内联函数。
//而不管你是否有关键字inline

  4. 作为成员接口函数对类中的私有成员和保护成员进行读写

//作为成员接口函数对类中的私有成员和保护成员进行读写。
class RW
{public:int Readi(){return _i;}void Seti(int i){_i = i;}
private:int _i;
};

三、优缺点

3.1 内联函数的优缺点?

优点:

  1. 因为内联函数是函数,函数参数有类型,因此在编译阶段会进行参数类型检测,安全性更高
  2. 在Debug模式下默认不会展开,可以进行调试,也可以通过对编译器设置来验证到底是否展开
  3. 内联函数不用像宏函数那样到处加括号,实现起来更简单
  4. 不会有副作用
  5. 内联函数在编译阶段已经展开,少了函数的调用,提高函数的运行效率

缺点:

  1. 每个使用内联函数的位置几乎都会被展开,会造成代码膨胀。

3.2 宏的优缺点?

(1) 宏常量的优缺点

  优点:一改全改,降低出错概率,提高代码的可读性

  缺点:在预处理节点进行替换,不会进行类型检测,代码安全性低

  因此在C++中建议尽量使用const修饰的常量替换宏常量。

(2) 宏函数的优缺点

  优点:

  • 不是函数,少了函数调用的开销,提高程序的运行效率
  • 可少些一些代码,因为宏函数可以封装多条语句
  • 可提高代码的可读性

  缺点:

  • 宏函数预处理阶段被替换,不会进行类型的检测,代码安全性低
  • 宏函数不能进行调试
  • 容易出错,宏函数的每一部分都需要加上括号
  • 每个宏函数的位置都会被展开,会造成代码的膨胀
  • 宏函数可能会有副作用

四、笔试题

4.1 为什么要是用宏,宏有什么优缺点?

  因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地 址,将函数的内容执行完后再返回到转去执行该函数前的地方。这种转移操作要求在转去执行前要保存现场并记忆执行的地址,转回后要恢复现场,并按原来保存地址继续执行。因此函数调用要有一定的时间和空间方面的开销,于是将影响其效率。而宏只是在预处理的地方将代码展开,不需要额外的空间和时间方面的开销,所以调用一个宏比调用一个函数更有效率。

​   优点:
​     1.增强代码的复用性。
​      2.提高性能与可读性。
​   缺点:
​      1.不方便调试宏。(因为预编译阶段进行了替换)
​      2.导致代码可读性差,可维护性差,容易产生二义性。
​      3.没有进行类型的检测 ,安全性低。

4.2 宏函数与内联函数的区别?

  内联函数和宏的区别在于:宏是由预处理器对宏进行替换的,而内联函数是通过编译器控制实现的,宏是在预处理阶段进行替换,内联函数是在编译阶展开的。而且内联函数是真正的函数,只是在需要用到的时候内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。所以可以像调用函数一样来调用内联函数,而不必担心会产生像宏出现的问题。

第三题:C++有哪些技术替代宏?

​    1.常量定义 换用 const修饰的常量

​    2.函数定义 换用 内联函数

4.3 C++中被const修饰的变量已经是常量,具有宏替换属性

const int a=10;
int arry[a]={0};

  在C++中能够编译通过,a被const修饰,a为常量表达式

  在C编译器中就编译报错,这是因为在C语言中,被const修饰的变量不能称其为常量,仍旧是变量,只不过该变量不能够被修改。即在C语言中,被const修饰的变量是一个不能修改的变量,不能被称为常量。


五、总结

  1. 在C++中强制建议使用const来代替宏常量使用内联函数来代替宏函数
  2. const和内联函数在进行编译时不仅进行替换,而且还会进行参数类型检测,提高了程序的安全性。
  3. 内联函数可以是普通函数,也可以是类的成员函数;函数式宏不能作为类的成员函数。


【C/C++】宏函数与内联函数的区别相关推荐

  1. 宏定义和内联函数的区别

    宏定义和内联函数都是为了使得程序减少函数的调用而花费的开销,提高了执行效率 宏定义只是作简单的文本替换,而内联函数则是在调用出展开 宏定义在预处理时作替换,而内联函数在编译时展开 内联函数会做类型.语 ...

  2. 宏定义,宏函数和内联函数

    宏定义,宏函数和内联函数 宏是什么: 简单宏替换出现的问题: 带参数的宏定义(宏函数): 宏的优点: 宏的缺陷,内联函数的引入 内联函数(空间换时间) 宏是什么: 宏(#define)命令是C语言中的 ...

  3. C++宏函数和内联函数

    C++宏函数和内联函数 1. 宏常量&宏函数 1.1 定义 // a. 定义一个宏常量 #define MAX 1024 // 宏常量 MAX称为符号常量// b. 定义一个宏函数 // 宏函 ...

  4. 对普通函数、宏函数、内联函数的作用机制的探索

    这次我们来分析的是C/C++程序员经常遇到的问题,如何在普通函数.宏函数.内联函数之间做取舍,其实它们三者之间并没有什么绝对的你好我差的说法,只要掌握了三者的作用机制的话,结合实际情况一般都能做出正确 ...

  5. mysql 内联函数_内联函数 - freeboy小亮 - 博客园

    (1)什么是内联函数? 内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内. (2)为什么要引入内联函数? 当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题.另外,前面我们 ...

  6. java内联函数_Java之内联函数_内联函数的优缺点

    描述 内联函数 1.内联函数就是指函数在被调用的地方直接展开,编译器在调用时不用像一般函数那样,参数压栈,返回时参数出栈以及资源释放等,这样提高了程序执行速度. 2.Java语言中有一个关键字fina ...

  7. 拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元

     1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: ...

  8. 宏定义和内联函数的学习

    宏定义可以提高效率,但是宏不是函数. 预编译通过代码复制的方式代替函数调用,省去了诸如函数压栈等系统过程,从而提高了效率.但是由于宏定义仅仅是代码替换,所以引起很多问题. #define  MAX(a ...

  9. c++中内敛函数_C++ 内联函数 | 菜鸟教程

    内联函数: Tip: 只有当函数只有 10 行甚至更少时才将其定义为内联函数. 定义: 当函数被声明为内联函数之后, 编译器会将其内联展开, 而不是按通常的函数调用机制进行调用. 优点: 当函数体比较 ...

最新文章

  1. 慕课网基于ElasticSearch的找房网实战开发企业级房屋搜索网项目学习心得(一)
  2. Web 页面请求过程
  3. Node.js 入门到干活,10 个优质项目就够了!
  4. IEEE公布2.5G和5G以太网IEEE 802.3bz标准
  5. Winsock属性 方法介绍
  6. eas之Uuid和BOSUuid 区别
  7. CC_STACKPROTECTOR防内核堆栈溢出补丁分析【转】
  8. 基于PSCAD输电线路潮流计算
  9. 华为性格面试的技巧方法
  10. 淘宝关于用户行为的数据分析
  11. 神经网络学习小记录64——Pytorch 图像处理中注意力机制的解析与代码详解
  12. nginx用法总结【1】
  13. 一口气搞懂「Flink Metrics」监控指标和性能优化,全靠这33张图和7千字(建议收藏)
  14. 【配电网重构】基于粒子群算法实现最小化功率损耗的配电网重构附matlab代码
  15. 网易云信IM即时通讯PHP接口开发
  16. 华为南研所2015年面试经历总结
  17. Scratch3.0新手入门教程
  18. 真科技向善!全网黑客,都在帮一个脑瘫女孩破解软件!
  19. pdk7105的I2C配置
  20. Silvaco三维仿真

热门文章

  1. 相机模型之鱼眼模型(Equidistant)
  2. 相机模型-鱼眼模型(fisheye camera model)
  3. jenkins中jdk配置_如何在Jenkins中配置JDK
  4. ubuntu20.04下出现protoc与gazebo版本问题
  5. matlab需要64g内存吗,买128G的手机有必要吗?64G手机内存会不够用么?
  6. fetch的简单使用
  7. 进军时尚界!梅西推出个人服装品牌“梅西”
  8. 梅科尔工作室-王佩茜-鸿蒙笔记3
  9. 使用MFC界面库LibUIDK
  10. 前端学习之vue的生命周期函数