C++ 基础 003 inline内联函数话题

inline内联函数话题

/*
 *运行平台:Visual Studio 2015
 *参考资料:《C++ Primer Plus(第6版)》,传智扫地增C++基础课程
*/


一、前言

在讲inline内联函数之前,先问大家一个
  问题C++中的const常量可以在一定程度上替代宏常数定义,那么是否有解决方案替代宏代码片段呢?
  回答:肯定有的,毕竟C++是对C的升级嘛,C++中推荐使用内联函数替代宏代码片段

二:那么怎么使用呢?

   在C++中使用inline关键字声明内联函数,声明时inline关键字必须和函数定义结合在一起否则编译器会直接忽略内联请求。如:inline void get();

三、注意

1、内联函数生成的代码中是没有定义的

  C++编译器直接将函数体插入在函数调用的地方 ,内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)。
  因此,当函数体的执行开销远大于压栈,跳转和返回所用的开销时,那么内联将无意义。

inline void get()
{
	printf("Hello\n");
} 
int main()
{
	get();
	/* 相当于 */
	{
		printf("Hello\n");
	}
}

2、C++编译器不一定准许函数的内联请求

  内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)。内联函数是对编译器的一种请求,既然是请求,那么肯定可以拒绝,因此编译器可能拒绝这种请求

3、inline与宏代码片段区别

  内联函数编译器处理,直接将编译后的函数体插入调用的地方。
  宏代码片段预处理器处理, 进行简单的文本替换有任何编译过程

4、C++编译器能够进行编译优化

  现代C++编译器能够进行编译优化,因此一些函数即使没有inline声明,也可能编译器内联编译

5、C++中内联编译的限制

  • 能存在任何形式的循环语句
  • 能存在过多的条件判断语句
  • 函数体过于庞大
  • 能对函数进行取址操作
  • 函数内联声明必须在调用语句之前

6、inline替代宏代码片段就可以避免宏的副作用

用一段程序来说明:

#include "iostream"
using namespace std;

#define MYFUNC(a, b) ((a) < (b) ? (a) : (b))  
inline int myfunc(int a, int b) 
{
	return a < b ? a : b;
}

int main()
{
	int a = 1;
	int b = 3;
	
	int c = myfunc(++a, b); 
	printf("a = %d\n", a); 
	printf("b = %d\n", b);
	printf("c = %d\n", c);
	
	c = MYFUNC(++a, b);  
	printf("a = %d\n", a); 
	printf("b = %d\n", b);
	printf("c = %d\n", c);

	system("pause");
	return 0;
}

结果:可以看到两者执行的结果不一致,因此使用#define定义代码块时可能会造成一定的副作用。
在这里插入图片描述
解释:
在这里插入图片描述

结论:

  1. 内联函数在编译时直接将函数体插入函数调用的地方。
  2. inline只是一种请求,编译器不一定允许这种请求。
  3. 内联函数省去了普通函数调用时压栈,跳转和返回的开销。
发布了41 篇原创文章 · 获赞 31 · 访问量 3681

猜你喜欢

转载自blog.csdn.net/weixin_42813232/article/details/105478535