第6课 内联函数分析

1.  常量与宏回顾

(1)C++中的const常量可以替代宏常数定义,如:

  const int A = 3; ←→ #define A  3

(2)C++中是否有解决方案,可以用来替代宏代码片段呢?

2. 内联函数

2.1 内联函数的定义

(1)C++编译器可以将一个函数进行内联编译,被C++编译器内联编译的函数叫内联函数

(2)C++中使用inline关键字声明内联函数。如

inline int func(int a, int b)
{
    return a < b ? a : b;
}

(3)内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。(注释:经测试在vs2013下,inline放在声明或定义前均可以

2.2 内联函数的特点

(1)C++编译器直接将内联函数的函数体插入到函数调用的地方

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

(3)C++中推荐使用内联函数替代宏代码片段。

(4)C++编译器也不一定满足函数的内联请求

【编程实验】内联函数初探

                   

左图:内联函数没嵌入到调用地方(仍为函数调用)                            右图:函数体被嵌入到调用的地方

#include <stdio.h>

#define FUNC(a, b) ((a) < (b) ? (a) : (b))

//MSVC下:要让inline、__forceinline生效必须得做如下的设置:
//①在“项目”→“配置属性”→“C / C++” →“优化”→“内联函数扩展”中选择“只适用于__inline(/ Ob1)”
//②在“配置属性”→“C / C++” →“所有选项”→“调试信息格式”中选择“程序数据库( / Zi)”

inline int func(int a, int b) //VS2013下,inline可放在声明前或也可放在定义前。或两者前都加
{
    return a < b ? a : b;
}

int main()
{
    int a = 1;
    int b = 3;

    /*
    int c = FUNC(++a, b);//相当于(++a)<(b)?:(++a):(b);

    printf("a = %d\n", a); //3
    printf("b = %d\n", b); //3
    printf("c = %d\n", c); //3

    */

    int c = func(++a, b);

    printf("a = %d\n", a);     //2
    printf("b = %d\n", b); //3
    printf("c = %d\n", c);     //2

    return 0;
}

2.3 内联函数与宏的不同



内联函数


处理方式


预处理器处理,只是进行简单的文本替换


编译器处理,会将函数体嵌入到调用的地方。但内联请求也可能被编译器拒绝


类型检查


不做类型检查


具有普通函数的特征,会进行参数和返回类型的检查


副作用



【编程实验】内联函数深度示例

#include <stdio.h>

//MSVC2013下:在函数声明或定义前加inline或__forceinline都可以
//同时,这两个的表现行为几乎一模一样。只不过__forceinline是MS
//下的,而inline是标准C++的,可移植性更高。

//__forceinline
//__attribute__((always_inline))
//inline
int add_inline(int n); 

int main()
{
    int r = add_inline(10);

    printf("r = %d\n", r);

    return 0;
}

__forceinline int add_inline(int n)
{
    int ret = 0;

    for (int i = 0; i < n; i++)
    {
        ret += i;
    }

    return ret;
}

2.4 现代C++编译器对内联函数的优化

(1)现代C++编译器能够进行编译优化,一些函数即没有inline声明,也可能被内联编译。

(2)一些现代的C++编译器提供了扩展语法,可用下列列关键字替代inline来对函数进行强制内联,如:

  ①g++:__atrribute__((always_inline)) ②MSVC:__forceinline

(3)MSVC下:要让inline、__forceinline生效必须得做如下的设置

  ①在“项目”→“配置属性”→“C/C++” →“优化”→“内联函数扩展”中选择“只适用于__inline(/Ob1)”

  ②在“配置属性”→“C/C++” →“所有选项”→“调试信息格式”中选择“程序数据库(/Zi)”

3. C++中inline内联编译的限制

(1)含有递归调用的函数不能设置为inline

(2)使用了复杂流程控制语句:循环语句和switch语句,无法设置为inline(说明:如上述实例,在VS2013下,循环语句是可以被内联的)

(3)函数体不能过于庞大

(4)不能对函数进行取址操作

(5)函数内联声明必须在调用语句之前.

4. 小结

(1)C++中可以通过inline声明内联函数

(2)编译器直接将内联函数体扩展到函数调用的地方

(3)inline只是一种请求,编译器不一定允许这种请求

(4)内联函数省去了函数调用时压栈、跳转和返回开销

时间: 2024-12-12 12:08:19

第6课 内联函数分析的相关文章

内联函数分析

目录 1. 内联函数的声明 2. 内联函数的特性 3. 内联函数与编译器 4. 内联函数的限制 1. 内联函数的声明 在C++中,const常量可以代替宏常数定义,而宏代码段则推荐使用内联函数来代替. C++中使用inline关键字声明内联函数 inline只是一种请求,编译器不一定允许这种请求 inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求 inline int func(int a, int b) { return a < b ? a : b; } 2. 内联函数的

拷贝构造,深度拷贝,关于delete和default相关的操作,explicit,类赋初值,构造函数和析构函数,成员函数和内联函数,关于内存存储,默认参数,静态函数和普通函数,const函数,友元

 1.拷贝构造 //拷贝构造的规则,有两种方式实现初始化. //1.一个是通过在后面:a(x),b(y)的方式实现初始化. //2.第二种初始化的方式是直接在构造方法里面实现初始化. 案例如下: #include<iostream> //如果声明已经定义,边不会生成 class classA { private: int a; int b; public: //拷贝构造的规则,有两种方式实现初始化 //1.一个是通过在后面:a(x),b(y)的方式实现初始化 //2.第二种初始化的方式是直

C++引用,内联函数,函数重载二义性总结_C++

1.引用 1.1 引用的概念 C++语言中,可以定义"引用".引用定义如下: 类型名 & 引用名 = 同类型的某变量名: 例如:int n: int &r=n://r就是一个引用,可以说r的类型是int &,r引用了变量n,或者说r成为n的引用. 某个变量的引用和这个变量是一回事,相当于该变量的一个别名.请注意,定义引用时一定要将其初始化,否则编译不会通过,通常会用某个变量去初始化引用,初始化后,它就一直引用该变量,不会再引用别的变量了.也可以用一个引用去初始化

C++学习笔记之——内联函数,引用

本文为原创作品,转载请注明出处 欢迎关注我的博客:http://blog.csdn.net/hit2015spring和http://www.cnblogs.com/xujianqing/ 作者:晨凫追风 一直想开始写C++的学习笔记,学习C++已经两个月了,今天开始写一下引用,内联函数,的一些概念和作用吧.那么开始吧! ????内联函数: 我们写的程序最终都是要用编译器,进行编译链接形成一段机器可以知道的二进制代码,接着存到一个内存中,这时候每一段程序代码都会有自己的一个地址,计算机按照地址增

C++ 内联函数

1.定义: 被调用函数的函数体代码直接插入到该函数被调用处, 而不是通过call语句进行. 2.方式: (1).类的定义体外: 当在类的定义体外时,需要在该成员函数的定义前面加“inline”关键字,显式地告诉编译器该函数在调用时需要“内联”处理,如: class Person { public: string GetName(); private:   string  name; }; inline string GetName() {         return name; } (2).类

C++文件头,命名空间,new和delete,内联函数,引用,函数重载,构造函数和析构函数,深拷贝和浅拷贝,explict,this指针

 目  录 1       开始学习C++.............................................................................................................. 4 1.1       C++的头文件.................................................................................................

Java 内联函数

在说内联函数之前,先说说函数的调用过程. 调用某个函数实际上将程序执行顺序转移到该函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到  转去执行该函数前的地方.这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保  存地址继续执行.也就是通常说的压栈和出栈.因此,函数调用要有一定的时间和空间方面的开销.那么对于那些函数体  代码不是很大,又频繁调用的函数来说,这个时间和空间的消耗会很大. 那怎么解决这个性能消耗问题呢,这个时候需要引入内联函数了.内联函数

内联函数(五)

或许我们在 C 语言中听说过内联函数,但是内联函数是首先在 C++ 中提出来的,可能现代的 C 编译器支持内联函数. C++ 中的 const 常量可以代替宏常数定义,如:const int A = 3: <==> #define A 3:那么在 C++ 中是否有解决方案代替宏代码片段呢?在 C++ 中推荐使用内联函数替代宏代码片段,使用 inline 关键字声明内联函数.内联函数声明时 inline 关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求. C++ 编译器可以将一个函数

C++ 内联函数 摘自 C++ 应用程序性能优化

内联函数 在C++语言的设计中,内联函数的引入可以说完全是为了性能的考虑.因此在编写对性能要求比较高的C++程序时,非常有必要仔细考量内联函数的使用. 所谓"内联",即将被调用函数的函数体代码直接地整个插入到该函数被调用处,而不是通过call语句进行.当然,编译器在真正进行"内联"时,因为考虑到被内联函数的传入参数.自己的局部变量,以及返回值的因素,不仅仅只是进行简单的代码拷贝,还需要做很多细致的工作,但大致思路如此. 开发人员可以有两种方式告诉编译器需要内联哪些类