第3课 - 函数的升级(内联函数,默认参数,占位参数) - 上

xiaoxiao2021-02-28  17

第3课 - 函数的升级 - 上

    一.内联函数的使用

        1.C++推荐使用内联函数替代宏代码片段

        2.C++使用关键字inline关键字声明内联函数

            注意:inline关键字必须放在函数定义的地方,不能放在函数声明的地方,否则编译器会直接忽略内联请求

        inline int func (int a, int b)

        {

            return (a < b ? a : b );

        }

        3.内联函数的具体说明

            3.1 C++可以将一个函数进行内联编译

            3.2 被C++编译器内联编译的函数叫做内联函数

            3.3 内联函数在最终生成的代码中是没有定义的

            3.4 C++编译器直接将函数体插入函数调用的地方

                (例如当函数调用上面的func函数的时候会直接将该函数的函数体 (a < b ? a : b)插入调用的地方)

                调用func (1,2)就相当于 1 < 2 ? 1 : 2

            3.5 内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)

            

                注意:C++编译器不一定会准许函数的内联请求,如果不允许 !

            

           3.6 内联函数是一种特殊的函数,具有普通函数的特征

        4.内联函数与宏代码片段的区别

            4.1 内联函数有编译器处理,直接将编译后的函数体插入到调用的地方,宏代码片段有预处理器处理,进行简单的文本替换,没有任何编译过程

            4.2 效率上内联函数与宏代码片段一样,但是内联函数更安全。 具体见Source Example 4.1:

              

        Source Example 4.1: #include <iostream> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ #define FUNC(a,b) ((a) < (b) ? (a) : (b)) inline int func (int a, int b) { return (a < b ? a : b ); } int main(int argc, char** argv) { int a = 1; int b = 3; //int c = func(++a,b); int c =FUNC(++a,b); printf ("a = %d\n", a); printf ("b = %d\n", b); printf ("c = %d\n", c); return 0; }

 

                当使用内联函数时,相当于 2 < 3 ? 2 : 3

 

                输出结果a=2,b=3,c=2,正常。

                    

                当使用宏定义时,相当于 ++a < b ? ++a : b,即 3 < 3 ? 3 : 3

                输出结果变为a=3,b=3,c=3,a自增了两次,并不是我们所想要的结果,这就是宏定义的副作用。

            4.3 关于内联函数是否会被内联编译的具体说明

                a.C++编译器能够进行编译优化,因此一些函数即使没有inline声明也可能被编译器内联编译

                b.一些现代C++编译器提供了扩展语法,能够对函数进行强制内联,例如g++中的__attribute__((always_inline))属性

            4.4 内联函数的深度示例

              

         Source Example 4.4: #include <iostream> /* run this program using the console pauser or add your own getch, system("pause") or input loop */ inline int f_inline(int a, int b); int g_no_inline(int a, int b); int main(int argc, char** argv) { int r1 = f_inline(1,2); int r2 = g_no_inline(1,2); return 0; } int f_inline(int a, int b) { return a < b ? a : b; } int g_no_inline(int a, int b) { return a < b ? a : b; }

                    将该文件通过g++编译器编译,得到汇编文件。

                    在main函数的汇编代码中

                

         main: pushq %rbp .seh_pushreg %rbp movq %rsp, %rbp subq $48, %rsp .seh_stackalloc 48 .seh_setframe %rbp, 48 .seh_endprologue movl
转载请注明原文地址: https://www.6miu.com/read-2150375.html

最新回复(0)