天津网站制作维护,做实验教学视频的网站,莲花网,简洁大气网站模板c从c中继承的一个重要特征就是效率。假如c的效率明显低于c的效率#xff0c;那么就会有很大的一批程序员不去使用c了。 在c中我们经常把一些短并且执行频繁的计算写成宏#xff0c;而不是函数#xff0c;这样做的理由是为了执行效率#xff0c;宏可以避免函数调用的开销从c中继承的一个重要特征就是效率。假如c的效率明显低于c的效率那么就会有很大的一批程序员不去使用c了。 在c中我们经常把一些短并且执行频繁的计算写成宏而不是函数这样做的理由是为了执行效率宏可以避免函数调用的开销这些都由预处理来完成。 但是在c出现之后使用预处理宏会出现两个问题 1.第一个在c中也会出现宏看起来像一个函数调用但是会有隐藏一些难以发现的错误。 2.第二个问题是c特有的预处理器不允许访问类的成员也就是说预处理器宏不能用作类类的成员函数。 为了保持预处理宏的效率又增加安全性而且还能像一般成员函数那样可以在类里访问自如c引入了内联函数(inline function). 内联函数为了继承宏函数的效率没有函数调用时开销然后又可以像普通函数那样可以进行参数返回值类型的安全检查又可以作为成员函数。 预处理宏的缺陷 预处理器宏存在问题的关键是我们可能认为预处理器的行为和编译器的行为是一样的。当然也是由于宏函数调用和函数调用在外表看起来是一样的因为也容易被混淆。但是其中也会有一些微妙的问题出现: 问题一 #define ADD(x,y) xy
inline int Add(int x,int y){return x y;
}
void test(){int ret1 ADD(10, 20) * 10; //希望的结果是300int ret2 Add(10, 20) * 10; //希望结果也是300cout ret1: ret1 endl; //210cout ret2: ret2 endl; //300
} 问题二 #define COMPARE(x,y) ((x) (y) ? (x) : (y))
int Compare(int x,int y){return x y ? x : y;
}
void test02(){int a 1;int b 3;//cout COMPARE(a, b): COMPARE(a, b) endl; // 3cout Compare(int x,int y): Compare(a, b) endl; //2
} 问题三: 预定义宏函数没有作用域概念无法作为一个类的成员函数也就是说预定义宏没有办法表示类的范围。 内联函数基本概念 在c中预定义宏的概念是用内联函数来实现的而内联函数本身也是一个真正的函数。内联函数具有普通函数的所有行为。唯一不同之处在于内联函数会在适当的地方像预定义宏一样展开所以不需要函数调用的开销。因此应该不使用宏使用内联函数 n 在普通函数(非成员函数)函数前面加上inline关键字使之成为内联函数。但是必须注意必须函数体和声明结合在一起否则编译器将它作为普通函数来对待。 inline void func(int a); 以上写法没有任何效果仅仅是声明函数应该如下方式来做: inline int func(int a){return ;} 注意: 编译器将会检查函数参数列表使用是否正确并返回值(进行必要的转换)。这些事预处理器无法完成的。 内联函数的确占用空间但是内联函数相对于普通函数的优势只是省去了函数调用时候的压栈跳转返回的开销。我们可以理解为内联函数是以空间换时间。 类内部的内联函数 为了定义内联函数通常必须在函数定义前面放一个inline关键字。但是在类内部定义内联函数时并不是必须的。任何在类内部定义的函数自动成为内联函数。 class Person{
public:Person(){ cout 构造函数! endl; }void PrintPerson(){ cout 输出Person! endl; }
} 构造函数Person成员函数PrintPerson在类的内部定义自动成为内联函数。 内联函数和编译器 内联函数并不是何时何地都有效为了理解内联函数何时有效应该要知道编译器碰到内联函数会怎么处理 对于任何类型的函数编译器会将函数类型(包括函数名字参数类型返回值类型)放入到符号表中。同样当编译器看到内联函数并且对内联函数体进行分析没有发现错误时也会将内联函数放入符号表。 当调用一个内联函数的时候编译器首先确保传入参数类型是正确匹配的或者如果类型不正完全匹配但是可以将其转换为正确类型并且返回值在目标表达式里匹配正确类型或者可以转换为目标类型内联函数就会直接替换函数调用这就消除了函数调用的开销。假如内联函数是成员函数对象this指针也会被放入合适位置。 类型检查和类型转换、包括在合适位置放入对象this指针这些都是预处理器不能完成的。 但是c内联编译会有一些限制以下情况编译器可能考虑不会将函数进行内联编译 ü 不能存在任何形式的循环语句 ü 不能存在过多的条件判断语句 ü 函数体不能过于庞大 ü 不能对函数进行取址操作 内联仅仅只是给编译器一个建议编译器不一定会接受这种建议如果你没有将函数声明为内联函数那么编译器也可能将此函数做内联编译。一个好的编译器将会内联小的、简单的函数。转载于:https://www.cnblogs.com/mmc9527/p/10429683.html