惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
博客园 - Franky
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
爱范儿
爱范儿
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
博客园_首页
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recent Announcements
Recent Announcements
Scott Helme
Scott Helme
有赞技术团队
有赞技术团队
M
MIT News - Artificial intelligence
C
CERT Recently Published Vulnerability Notes
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Jina AI
Jina AI
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
L
LangChain Blog
L
LINUX DO - 最新话题
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
H
Hacker News: Front Page
MyScale Blog
MyScale Blog
P
Palo Alto Networks Blog
G
Google Developers Blog
Google DeepMind News
Google DeepMind News
AI
AI
T
Troy Hunt's Blog
Microsoft Azure Blog
Microsoft Azure Blog
阮一峰的网络日志
阮一峰的网络日志
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Vercel News
Vercel News
Microsoft Security Blog
Microsoft Security Blog
罗磊的独立博客
S
Secure Thoughts
大猫的无限游戏
大猫的无限游戏
博客园 - 叶小钗
人人都是产品经理
人人都是产品经理
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
S
Security @ Cisco Blogs
Cloudbric
Cloudbric
E
Exploit-DB.com RSS Feed
Attack and Defense Labs
Attack and Defense Labs

博客园 - 迷失天堂

映射模式 vc++入门宝典 图象的渐显/渐隐 关于:error LNK2001:unresolved external symbol F11可以切换浏览器状态 const用法 Spy++的用途 Windows 取得程序运行的路径 VC界面开发,我的一些小知识点 在VC中启动另外一个程序(.exe、...)方法 二值图像跟踪曲线程序 在MFC程序中使用VC Components visual c++键盘快捷键大全 在VC中实现扩展广告条 马骏 解决Windows 程序界面闪烁问题的一些经验 OpenGL FAQ CString 操作指南 新的Win32控件(转自:http://www.lzu.edu.cn/netteach/jiaochen/vc++5.0/vc++5.0/chap6/chap6_2.htm) 好用的快捷键推广
inline函数
迷失天堂 · 2005-05-11 · via 博客园 - 迷失天堂

inline函数 (转)
我们看下面的函数,函数体中只有一行语句:
    double Average(double total, int number){
      return total/number;
      }
定义这么简单的函数有必要吗?实际上,它还是有一些优点的:第一,它使程序更可读;第二,它使这段代码可以重复使用。但是,它也有缺点:当它被频繁地调用的时候,由于调用函数的开销,会对应用程序的性能(时间+空间效率,这儿特指时间)有损失。例如,Average在一个循环语句中重复调用几千次,会降低程序的执行效率。

    那么,有办法避免函数调用的开销吗?对于上面的函数,我么可以把它定义为内联函数的形式:
    inline double Average(double total, int number){
      return total/number;
    }
函数的引入可以减少程序的目标代码,实现程序代码的共享。
  函数调用需要时间和空间开销,调用函数实际上将程序执行流程转移到被调函数中,被调函数的代码执行完后,再返回到调用的地方。这种调用操作要求调用前保护好现场并记忆执行的地址,返回后恢复现场,并按原来保存的地址继续执行。对于较长的函数这种开销可以忽略不计,但对于一些函数体代码很短,又被频繁调用的函数,就不能忽视这种开销。引入内联函数正是为了解决这个问题,提高程序的运行效率。
    在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。由于在编译时将内联函数体中的代码替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间开销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。

总结:inline函数是提高运行时间效率,但却增加了空间开销。
       即inline函数目的是:为了提高函数的执行效率(速度)。
非内联函数调用有栈内存创建和释放的开销
在C中可以用宏代码提高执行效率,宏代码不是函数但使用起来像函数,编译器用复制宏代码的方式取代函数调用,省去了参数压栈、生成汇编语言的CALL调用、返回参数、执行return等过程,从而提高速度。

使用宏的缺点:(1)容易出错(预处理器在复制宏代码时常常产生意想不到的边际效应)
                  例如:#define MAX(a,b)    (a) > (b) ? (a) : (b)
                        语句result = MAX(i,j) + 2 却被扩展为result = (i)>(j)?(i):(j)+2;
                        但意却为result = ((i)>(j)?(i):(j)) + 2;
              (2)不可调试
              (3)无法操作类的私有数据成员

        C++函数内联机制既具备宏代码的效率,又增加了安全性,且可自由操作类的数据成员。 
        关键字inline必须与函数定义体放在一起才能使函数真正内联,仅把inline放在函数声明的前面不起任何作用。因为inlin是一种用于实现的关键字,不是一种用于声明的关键字。
        许多书籍把内联函数的声明、定义体前都加了inline关键字,但声明前不应该加(加不加不会影响函数功能),因为声明与定义不可混为一谈。

声明、定义和语句
声明:就是在向系统介绍名字(一个名字是一块内存块的别名),只是告诉编译器这个名字值的类型及宣告该名字的存在性,仅此而已。
定义:则是分配存储空间,即具有了存储类型。
语句:程序的基本组成部分,分可执行语句(定义是)和不可执行语句(声明是)。
在正式编写程序语句前定义的一些全局变量或局部变量,在C中为声明,C++中为定义。
例如:int  a;//在标C中为声明,是不可执行语句;在C++中为定义,是可执行语句
      extern int a;//为声明,是不可执行语句   CWinApp  curApp;//对象定义是可执行语句

◆使用内联函数时应注意以下几个问题:
(1) 在一个文件中定义的内联函数不能在另一个文件中使用。它们通常放在头文件中共享。
(2) 内联函数应该简洁,只有几个语句,如果语句较多,不适合于定义为内联函数。
(3) 内联函数体中,不能有循环语句、if语句或switch语句,否则,函数定义时即使有inline关键字,编译器也会把该函数作为非内联函数处理。
(4) 内联函数要在函数被调用之前声明。
例如:
#include <iostream.h>
int increment(int i);
inline int increment(int i){
  i++; return i;
}
void main(void){  ……
}
如果我们修改一下程序,将内联函数的定义移到main()之后:
    #include <iostream.h>
int increment(int i);
void main(void){  ……
}
//内联函数定义放在main()函数之后
inline int increment(int i){
  i++; return i;
}
内联函数在调用之后才定义,这段程序在编译的时候编译器不会直接把它替换到main中。也就是说实际上"increment(int i)"只是作为一个普通函数被调用,并不具有内联函数的性质,无法提高运行效率。