0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详细解析内联函数以及在C语言中的作用

5RJg_mcuworld 2017-12-21 14:21 次阅读

内联函数的作用

内联函数是一种编译机制,优点从代码上是看不出来的,但是程序的执行效率上有差别,通常,编译器对函数调用的处理是一种类似中断的方式,即当执行到函数调用语句时,程序把当前所有的状态信息比如CPU所有寄存器(其中一个很重要的就是指令指针寄存器)的值保存起来,然后放心大胆地转去执行那个函数的代码,执行完后再返回原来的地方,恢复原先保存过的状态信息,于是也就可以接着原来被中断的指令继续往下执行。

这样,就很容易实现代码的结构化,因为可以把一些独立的功能模块写成函数,函数内部的变量和外部的变量互不影响,而且函数执行完后就可以释放这个函数内部变量的所使用的内存空间(这就是为什么函数退出后,其内部变量不再有效),对内存的使用也是很经济的(否则,如果一个大的程序全部由一个函数组成,那么所有的变量都得自始至终地占用内存空间),当然,还有其他优点,比如可以实现递归,总之是好处多多。

可是,任何事情往往都有两方面,这样做虽然好处多多,但也是有代价的,那就是前面所说的,任何一次函数调用,程序都得进行保存和恢复状态信息的动作,用数据结构的术语说就是进栈和退栈,当然,还有内存分配的过程,如果函数的代码非常少,这种代价并不是可忽略的,比如说,你编写一个类,里面有个记录状态的成员变量:

Class MyClass

{

private:

int m_iState;

}

按照面向对象的思想,函数的属性应尽量的私有化,但外部怎么获得这个属性值呢?一般的方法就是加一个共有函数,这就实现的面向对象思想中所谓“通过公用接口操作对象的私有属性”。于是就变成了:

Class MyClass

{

public

int GetState();

private:

int m_iState;

}

int MyClass::GetState()

{

return m_iState;

}

这样一来,面向对象思想倒是体现出来了,但你的CPU会恨你:“你丫一个鸟函数就返回一个整数却让老子进一次栈、弹一次栈”,内存也会埋怨:“兄弟也得跟着分配内存!”

但对你来说,也很委屈,怎么办,把所有的属性都改成public?让外部内码直接访问?况且,那样也不解决所有问题,因为有时候即使不是为了面向对象,我们也需要把独立的功能模块做成函数,比如说产生随机数的函数。我想

int iRand=rand();

总比:

int iRand=((int)(MULTIPLIER * Seed + INCREMENT)》》16)&0x7fff;

看起来舒服吧?(我这里只是打个比方,VC的rand函数并不是内联函数)

而内联函数就是解决这个问题了,对于程序员,他还是把独立功能写成函数的形式,但只要声明为内联,编译器就不把它编译成一次函数调用,而只是类似于把函数的代码拷贝到被调用的地方,而且这完全是编译器私下里完成的,原来的访问权限等问题丝毫不受影响。这不是两全齐美了吗:在保证代码的面向对象性和结构化不受损失的条件下,程序的效率也没有损失,比如上面那个类,就变成了:

Class MyClass

{

public:

inline int GetState();

private:

int m_iState;

}

int inline MyClass::GetState()

{

return m_iState;

}

有一点要注意,内联函数要跟类的声明写在同一个文件中,否则编译会出错。按照VC管理源文件的风格来说,就是内联函数最好写在声明类的.h文件中,而不是像一般函数那样写在实现类的.cpp文件中。

当然,内联函数还有另外一种写法,就是直接写在类中,此时,不必使用“inline”关键字。

Class MyClass

{

public:

int GetState(){ return m_iState; }

private:

int m_iState;

}

最后,还要注意,内联函数只是一种编译机制,用上面两种形式声明的函数仅仅是建议编译器进行内联,而编译器是否内联不一定。正如前面所说,函数调用的开销只是对小的函数不可忽略,对于重量级的函数还是可以忽略的,而且在绝大多数的场合,函数调用才是人间正道,才是解决问题的最佳。所以大多数编译器并不把带有循环、递归等或者代码比较多的函数进行内联编译,有的甚至不允许声明成内联的。

C语言的内联函数的作用

[cpp] view plain copy关内联函数键字inline

[cpp] view plain copyvoid myprintf(int a)

{

priintf(“%d”,a);

}

int main()

{

for(i=0;i《100;i++)

myprintf(3);

}

对于这个函数,在进行反复的打印3的过程中我们是不是要反复的调用myprintf(int a)这个函数,进函数和出函数是需要时间的,假设这个过程用时为4ms,而执行printf这个操作只需要2ms,那么在100次循环的过程中进出函数的时间比函数功能printf需要的时间还要长,这样很影响工作效率。于是,我们就想要如何去免去进出函数的过程呢?那么就可以声明inline这个关键字,有何用途?当我们声明了一个inline的函数时候,函数被调用的语句就被替换成了函数本身,进行了一个预处理

[cpp] view plain copyint main()

{

for(i=0;i《100;i++)

void myprintf(3)

{

printf(“%d”,3);

}

return 0;

}

这样一来我就非常明显的知道这个函数是干什么的了,就不需要去调用函数的定义部分,再通俗点讲,原来我要从家里去外面的商店去买冰淇淋(来回需要时间),现在商店就在我家里面了,那么我是不是省去了去商店的时间呢?但是相应的我这个家要很大(也就是所谓的空间要很大才能包含这个商店对吧?)这样就是用空间去换取了时间了。

内联函数在编译层面类似于宏替换。也就是说,程序执行过程中调用内联函数不需要入栈出栈,所以效率会提高。

[cpp] view plain copy#include《stdio.h》

inline int add(int x, int y)

{

return x+y;

}

int main()

{

int i,j,k;

printf(“请输入两个整数的值:”);

scanf(“%d%d”,&i,&j);

k=add(i,j);

printf(“k=%d\n”,k);

return 0;

}


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    180

    文章

    7522

    浏览量

    127423
  • 内联函数
    +关注

    关注

    0

    文章

    10

    浏览量

    2191

原文标题:内联函数在C语言中的作用

文章出处:【微信号:mcuworld,微信公众号:嵌入式资讯精选】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    内联函数定义 为什么需要内联函数

    inline关键字是C99标准的型关键字,其作用是将函数展开,把函数的代码复制到每一个调用处。
    的头像 发表于 02-19 12:20 254次阅读

    如何给C语言中函数定义两个不同的名字?

    最近有位哥问我,如何给C语言中函数定义两个不同的名字?就是这两个名字都是指向同一个函数,同一个地址,而且两个名字都可以当做函数来用的那种。
    的头像 发表于 12-19 16:21 301次阅读

    c语言中函数函数体用什么符号括起来

    函数 是指将一组能完成一个功能或多个功能的语句放在一起的 代码结构 。 在 C语言程序 中,至少会包含一个函数,及主函数main()。本文将详细
    的头像 发表于 11-24 15:52 292次阅读
    c<b class='flag-5'>语言中</b><b class='flag-5'>函数</b>的<b class='flag-5'>函数</b>体用什么符号括起来

    scanf在C语言中作用

    scanf在C语言中作用  scanf是C语言中的输入函数,用于从标准输入设备(如键盘)读取数据,并将其存储到变量中。它是C语言中最常用的
    的头像 发表于 11-23 14:13 553次阅读

    C语言中链表的作用是什么?

    C语言中指针用的很少,链表、文件操作几乎没用过,所以也不能理解到底有什么作用。各位有经常在做程序时会用到这些吗。
    发表于 11-06 06:23

    宏的缺陷与内联函数的引入

    。 所以为了解决这种不利于调试的问题,就有了内联函数。 那么什么是内联函数呢? 我们以inline修饰的函数叫做
    的头像 发表于 11-01 17:57 226次阅读

    C语言中ASCII代码是什么意思?

    C语言中ASCII代码是什么意思常见的ASCII代码都需要记吗
    发表于 10-25 07:10

    C51中断函数和汇编语言中断服务程序在用法上有什么不同?

    C51中断函数和汇编语言中断服务程序在用法上有何不同?
    发表于 10-17 08:31

    请问链表单片机C语言中有应用吗?

    链表单片机C语言中有应用么?
    发表于 10-16 07:28

    C语言中memmove函数的使用

    在C语言编程中,内存操作是不可或缺的一部分,而 memmove 函数是其中一个重要的工具。本文将介绍 memmove 函数的应用场景以及提供详细
    发表于 09-13 09:17 662次阅读

    C语言中宏定义的应用

    在C语言中,宏定义是一种预处理指令,用于在代码中定义和使用常量、函数或代码片段的替代。
    发表于 08-17 15:33 385次阅读

    C语言中函数的基本知识

    函数是C语言中的基本构建块之一,它允许我们将代码组织成可重用、模块化的单元。
    发表于 08-16 18:25 378次阅读

    C语言中指针函数函数指针的概念及应用示例

    在C语言中,指针函数函数指针是强大且常用的工具。它们允许我们以更灵活的方式处理函数和数据,进而扩展程序的功能。
    发表于 08-16 16:14 334次阅读

    c语言中并没有变量zero的定义是怎么回事?

    的内嵌汇编语言。 目前的问题是第一句汇编指令不能完全理解, 以及c语言中并没有变量zero的定义是怎么回事
    发表于 08-16 07:58

    C语言中函数的返回值指向一个指针

    函数的返回值类型必须与函数体内的返回表达式的类型相匹配。如果类型不匹配,编译器会报错。此外,C 语言中函数只能返回一个值,如果需要返回多个值,可以使用结构体或指针等方式来实现。 返回
    的头像 发表于 04-26 11:01 1993次阅读
    C<b class='flag-5'>语言中</b><b class='flag-5'>函数</b>的返回值指向一个指针