内联函数
问题
调用函数入栈次数过多
#include <stdio.h>
int square(int);
int main(int argc, char const *argv[])
{
int i = 1;
while (i <= 100)
{
printf("%d 的平方是 %d\n", i - 1, square(i++));
//pritf函数参数的入栈顺序从右到左
}
return 0;
}
int square(int n)
{
return n * n;
}
内联函数
在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。
为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。
栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足所造成的程式出错的问题,函数的死循环递归调用的最终结果就是导致栈内存空间枯竭。
//
// Created by a1073 on 2019/7/6.
//
#include <stdio.h>
inline const char *string_test(int n) {
if (n % 2 > 0) {
return "奇";
} else {
return "偶";
}
}
int main(void) {
for (int i = 1; i < 101; ++i) {
printf("%d 奇偶性是%s\n", i, string_test(i));
}
return 0;
}
- 上面的例子就是标准的内联函数的用法,使用inline修饰带来的好处我们表面看不出来,其实在内部的工作就是在每个for循环的内部任何调用dbtest(i)的地方都换成了(i%2>0)?“奇”:"偶"这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗。
- 关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。
- inline只适合涵数体内代码简单的函数数使用,不能包含复杂的结构控制语句例如while、switch,并且内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。
- 内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。
以下情况不宜使用内联:
(1) 如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
(2) 如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。