### C语言关键字浅析系列 ###
### ISO/ANSI C 关键字 ###
inline关键字是C99标准新增的,是在某些方面比较实用的一个关键字
inline常出现在定义内联函数的地方,这也是它最重要的使命
inline的作用是:
定义内联函数。
1、何为内联函数?
内联函数的提出与C语言本身的一些特质有关,众所周知,C语言中,函数被调用时会在内存中被调入函数栈
如果有这么一个或多个函数,它们会非常频繁地被调用(如递归情况),则会导致不断地有函数入栈,而栈空间是有限的
在代码维护不精的情况下很可能造成栈空间浪费甚至耗尽,如果被调用的函数体本身不是很大,则执行的性价比是不高的
这时,我们引入了inline和内联函数的概念:
C语言里,某个函数调用一个内联函数时,会将内联函数的代码复制到调用处。
比如下面这个例子:
#include <stdio.h>
inline char* judgeResult(int goal)
{
return (goal > 3) ? "赢" : "输"; /* 扔色子,3以上为大,买赢 */
}
int main(void)
{
int goal = 0;
while (1)
{
shaking(&goal); /* 摇注中 */
printf("摇出%d,庄家%s", goal, judgeResult(goal)); /* 打印结果 */
}
return 0;
}
这段代码其实从技术上来看,就是把main函数中的judgeResult(goal)处全替换成了(goal > 3) ? "赢" : "输"
虽然上面这个例子中的内联函数的调用频率似乎并不高,但也说明了内联函数的原理,即代码复制
如果你顿悟了,你就会突然发现inline的好处了:上述代码中,调用内联函数并没有开辟新的栈空间,而只是在不断调用这段代码
所以对于那些频繁调用的函数,如果使用内联的形式比开辟栈空间来得更划算和高效,不妨使用内联函数
怎么叫做更高效呢?比如一个只有一条语句的函数,却要十分十分频繁地被调用,开辟栈空间消耗很大
或者说等同于用要寄一张身份证复印件,你说是通过大件物流公司好还是传真机好呢?
2、inline的格式
这是一条规定:inline需要和函数名放在一起才能表示为内联函数
比如上面那个例子中的内联函数:
char* judgeResult(int goal); /* 这是函数的声明,inline放在此处是无效的 */
inline char* judgeResult(int goal) /* inline必须放在函数定义处的函数名前 */
{
return (goal > 3) ? "赢" : "输"; /* 扔色子,3以上为大,买赢 */
}
如果你想这样写,将无非是做无用功:
inline char* judgeResult(int goal); /* 函数声明处并不能表示函数为内联的 */
char* judgeResult(int goal)
{
return (goal > 3) ? "赢" : "输"; /* 扔色子,3以上为大,买赢 */
}
3、inline的风险
并不是所有函数都适合内联,不然你会发现你见过的很多C源代码的函数都有个帽子叫inline,而事实上不是
从内联函数的原理我们知道,它只是在被调用的时候把内联函数的代码复制到调用处
但如果内联函数的代码量很大呢?这时候就不适合作为内联函数来复制代码了,否则会造成代码膨胀
有一些编程上的技巧还是值得学习inline的人注意的:
(1)内联函数基本只适合代码量小且简单的函数,内联函数中尽量不要包含循环结构或switch结构等复杂控制结构
(2)内联函数不能自递归
(3)内联函数最好写在头文件中