C++ 内联函数
C++中,使用预处理宏存在俩问题:
(1).宏看起来像一个函数调用,但不总是这样,这样就隐藏了难以发现的问题(这个问题在C中也存在)
(2).这个问题是C++特有的:预处理器不允许访问类的成员数据。这意味着预处理器宏不能用作类的成员函数。
为了保持预处理器宏的效率又增加安全性,而且还能像一般成员函数一样可以在类里访问自如,C++引入了内联函数。
1.预处理宏
在C语言源程序中允许用一个标识符来表示一个字符串, 称为“宏”。被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换, 这称为“宏代换”或“宏展开”。
宏定义是由源程序中的宏定义命令完成的。 宏代换是由预处理程序自动完成的。
宏定义只是起到个替换功能,并不能作为函数使用,当宏定义的字符串是一个算数表达式的时候,就要为它加括号括住,不然在调用它的时候会出现意想不到的错误。如下例:
#include<stdio.h> #define M y*y+3*y int main() { int s, y; printf("input a number: "); scanf("%d", &y); s = 3 * M + 4 * M + 5 * M; printf("s=%d\n", s); return 0; }
这里输入的数字是2,即y=2。按照数学算法M=y*y+3*y =2*2+3*2=10,那么s=3*M+4*M+5*M=3*10+4*10+5*10=120。但是结果是66,为什么呢?因为宏执行的是替换,我们把M代表的字符串y*y+3*y替换到程序中,
得到:s=3*y*y+3*y + 4*y*y+3*y + 5*y*y+3*y。这样的话计算结果就是上图中的66。但是为字符串加括号的话就符合我们的预期,不会出错了。#define M (y*y+3*y),执行后:
2.内联函数:
一般把内联定义放在头文件里。
当编译器看到这个定义时,它把函数类型(函数名+返回值)和函数体放到符号表里。使用函数时,编译器检查以确保函数调用是否正确,且返回值被正确使用,然后将函数调用替换为函数体,因而减小开销。内联代码虽然占用空间,但如果函数较小,这样做却比一个普通函数调用而产生的代码(参数压栈和执行call)占用的空间还小。
定义内联函数,使用关键字inline:
1.错误定义:
inline int Function(int x);//只有函数声明,没有函数体
2.正确定义方法:
inline int Function(int x){return x;}//函数声明和函数体一起使用,正确。
任何在类内部定义的函数都自动的成为内联函数。但是在类外部定义的函数想要成为内联函数,要在函数前面加inline关键字使之成为内联函数,为了使之有效,必须使函数体和声明放在一起,否则,编译器将它作为普通函数对待。
一般把内联函数放在头文件里。在头文件中声明内联函数,必须包含该函数的定义,这些定义在每个用到该函数的文件中,不会出现多个定义错误的情况。