(一〇二)内联函数

简介:

元旦了,各种打不开博客。元旦结束,博客好了,是因为元旦放假程序员都回家了嘛?


————————————————————————————————

内联函数和普通函数有所区别。

 

普通函数需要①函数定义②函数原型③函数调用,具体调用形式是,先调用时,储存当前函数的内存地址(假设为地址A),然后调用函数,跳到被调用函数的内存地址(地址B),然后在地址B处依次执行,等执行完被调用的函数(或许还有返回值),再返回之前储存的地址A处。

 

内联函数,可以省略②函数原型(也可以不省略),但需要在函数定义和函数原型的函数头之前加上关键字inline(如果省略函数原型的话,则一般将函数定义放在函数原型的地方),

他的机制,是把函数代码,放在函数调用时的内存地址处,这样的话,无需像普通函数那样,从地址A处跳到地址B处,调用完再跳回来,而是地址A处之后的内存位置,就是原本是地址B处函数的代码内容。就像直接将函数命令放在调用处一样。

 

例如:

int main()
{
int a=x(1);

return 0;

}

int x(int m)

{
return m+3;

}

 

在普通函数时,int a的内存地址是地址A,而x函数被储存在地址B处(注意,BA并不一定相邻,或者说,几乎不会相邻)。于是程序访问内存时的顺序:地址A——地址B——地址A这样。

 

而在内联函数时,在int x(int m)之前加上inline,在main函数中,有点类似于:

int a={ 1 + 3 };

这样的形式。

 

由于内联函数是直接放在main函数中(而不是调用的时候才占用内存),因此,使用内联函数更耗费内存。但相对而言,使用内联函数的优点则是速度更快(因为不用在内存之中跳来跳去)。

 

但,由于在内存地址中跳来跳去速度其实很快,所以节省的时间的绝对值,并不大,除非该函数经常被调用(每次节约0.01秒,100次就是1秒了)。

 

内联函数的优点:速度更快——适合执行代码时间很短的函数;

内联函数的缺点:占用内存更多——不适合较长的函数。

 

 

编译器不允许使用内联函数的两种情况:

①递归函数——内联函数不允许自己调用自己;

②函数过大。

 

 

内联函数的使用方式:

①在函数原型和函数定义的函数头之前加上关键字inline即可;

 

②可省略函数原型,若省略,则将函数定义放置于函数原型处较好;

 

③其他同普通函数。

 

如代码:

#include<iostream>

inline int chengfang(int a)	//函数定义前置于函数原型处,并可省略函数原型
{
	return a*a;
}

int main()
{
	using namespace std;
	int b = chengfang(2);	//像普通函数那样调用内联函数
	int c = chengfang(5);
	cout << "b = " << b << ". c = " << c << endl;
	cin.get();
	return 0;
}

输出:

b = 4. c = 25


与内联函数对应的宏:

C语言中,使用预处理器语句#define来提供宏——内联代码的原始实现。

例如宏:#define SQUAR(X) X*X;

 

宏的特点是文本替换,而不像内联函数那样是函数调用——也就意味着,没有括号的情况下,结果和内联函数的结果不同。

define的代码:

#include<iostream>

#define square(x)	x*x;

int main()
{
	using namespace std;
	int a[5];
	a[0] = square(1);	//实质是1*1=1
	a[1] = square(2);	//实质是2*2=4
	a[2] = square(2 * 2);	//实质是2*2 * 2*2=16
	a[3] = square(2 + 2);	//实质是2 + 2*2 + 2=8
	a[4] = square(2 + 0);	//实质是2 + 0*2 + 0=2
	for (int i = 0;i < 5;i++)
		cout << "a[" << i << "] = " << a[i] << endl;
	system("pause");
	return 0;
}

输出:


a[0] = 1
a[1] = 4
a[2] = 16
a[3] = 8
a[4] = 2
请按任意键继续. . .


使用内联函数的代码:


#include<iostream>

inline int square(int x) { return x*x; }

int main()
{
	using namespace std;
	int a[5];
	a[0] = square(1);	//实质是1*1
	a[1] = square(2);	//实质是2*2=4
	a[2] = square(2 * 2);	//实质是(2*2) * (2*2)=16
	a[3] = square(2 + 2);	//实质是(2+2) * (2+2)=4*4=16
	a[4] = square(2 + 0);	//实质是(2+0) * (2+0)=2*2=4
	for (int i = 0;i < 5;i++)
		cout << "a[" << i << "] = " << a[i] << endl;
	system("pause");
	return 0;
}

输出:


a[0] = 1
a[1] = 4
a[2] = 16
a[3] = 16
a[4] = 4
请按任意键继续. . .

由上述两个例子可以看出,#define宏的效果,和inline内联函数的机制完全不同。

 

#define是文本替换,将括号里的内容直接赋值到表达式之中——而不是括号里表达式的结果。

 

inline是像函数调用那样,将表达式的值得出值的结果后,再放入函数内部的表达式之中。

 

特别是比如说:#define MM(m) m*m*m; 这样的宏,

当遇见调用int a=1; int b=MM(a++);时,

在代码中,b=1*2*3=6

而不是内联函数的b=1*1*1(因为a++是先执行完这行代码之后,a=a+1);

 


目录
相关文章
|
2月前
|
C语言 C++
C++(三)内联函数
本文介绍了C++中的内联函数概念及其与宏函数的区别。通过对比宏函数和普通函数,展示了内联函数在提高程序执行效率方面的优势。同时,详细解释了如何在C++中声明内联函数以及其适用场景,并给出了示例代码。内联函数能够减少函数调用开销,但在使用时需谨慎评估其对代码体积的影响。
|
6月前
|
编译器 C++
内联函数
内联函数
39 1
|
5月前
|
编译器 C++ 开发者
什么是内联函数?
综上所述,内联函数在C++中是一种重要的优化手段,特别是在类定义中,通过内联简单的成员函数,可以提高程序的执行效率、代码的可读性和维护性,同时为编译器提供更多的优化机会。然而,需要注意的是,并不是所有函数都适合内联,具体情况需要根据函数的复杂度和实际需求进行权衡。
39 0
|
6月前
|
缓存 安全 编译器
你了解内联函数吗?
你了解内联函数吗?
|
6月前
|
编译器 C语言 C++
【C++】内联函数
【C++】内联函数
48 1
|
6月前
|
安全 编译器 C++
【c++】内联函数
【c++】内联函数
【c++】内联函数
|
11月前
|
编译器 C++
C++内联函数
C++内联函数
39 0
|
编译器 数据库 C++
|
编译器 C++ 开发者
C++ 内联函数
C++ 内联函数
57 0
|
安全 编译器 C语言
C++之内联函数
C++之内联函数
68 0