元旦了,各种打不开博客。元旦结束,博客好了,是因为元旦放假程序员都回家了嘛?
————————————————————————————————
内联函数和普通函数有所区别。
普通函数需要①函数定义②函数原型③函数调用,具体调用形式是,先调用时,储存当前函数的内存地址(假设为地址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处(注意,B和A并不一定相邻,或者说,几乎不会相邻)。于是程序访问内存时的顺序:地址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);