• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > 深入探讨:宏、内联函数与普通函数的区别

深入探讨:宏、内联函数与普通函数的区别

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了内联函数和宏定义,宏与内联函数的异同,宏和内联函数,合富辉煌内联网,内联函数等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
内联函数的执行过程与带参数宏定义很相似,但参数的处理不同。带参数的宏定义并不对参数进行运算,而是直接替换
;内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然
后把表达式的值传递给形式参数。
    内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定;而带参数
宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患。
    使用内联函数时,应注意以下问题:
    1)内联函数的定义性声明应该出现在对该函数的第一次调用之前。
    2)内联函数首先是函数,函数的很多性质都适用于内联函数,如内联函数可以重载。
    3)在内联函数中不允许使用循环语句和switch结果,带有异常接口声明的函数也不能声明为内联函数。
先说宏和函数的区别:
1. 宏做的是简单的字符串替换(注意是字符串的替换,不是其他类型参数的替换),而函数的参数的传递,参数是有数据类
型的,可以是各种各样的类型.
2. 宏的参数替换是不经计算而直接处理的,而函数调用是将实参的值传递给形参,既然说是值,自然是计算得来的.
3. 宏在编译之前进行,即先用宏体替换宏名,然后再编译的,而函数显然是编译之后,在执行时,才调用的.因此,宏占用的
是编译的时间,而函数占用的是执行时的时间.
4. 宏的参数是不占内存空间的,因为只是做字符串的替换,而函数调用时的参数传递则是具体变量之间的信息传递,形参
作为函数的局部变量,显然是占用内存的.
5. 函数的调用是需要付出一定的时空开销的,因为系统在调用函数时,要保留现场,然后转入被调用函数去执行,调用完,
再返回主调函数,此时再恢复现场,这些操作,显然在宏中是没有的.
现在来看内联函数:
所谓"内联函数"就是将很简单的函数"内嵌"到调用他的程序代码中,只样做的目的是为了避免上面说到的第5点,目的旨
在节约下原本函数调用时的时空开销.但必须注意的是:作为内联函数,函数体必须十分简单,不能含有循环、条件、选择
等复杂的结构,否则就不能做为内联函数了。事实上,即便你没有指定函数为内联函数,有的编译系统也会自动将很简
单的函数作为内联函数处理;而对于复杂的函数,即便你指定他为内联函数,系统也不会理会的。

介绍内联函数之前,有必要介绍一下预处理宏。内联函数的功能和预处理宏的
功能相似。相信大家都用过预处理宏,我们会经常定义一些宏,如
#define TABLE_COMP(x) ((x)>0?(x):0)
就定义了一个宏。

  为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数
所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行
该函数前的地方。这种转移操作要求在转去执行前要保存现场并记忆执行的地
址,转回后要恢复现场,并按原来保存地址继续执行。因此,函数调用要有一
定的时间和空间方面的开销,于是将影响其效率。而宏只是在预处理的地方把
代码展开,不需要额外的空间和时间方面的开销,所以调用一个宏比调用一个
函数更有效率。

  但是宏也有很多的不尽人意的地方。
  1、.宏不能访问对象的私有成员。
  2、.宏的定义很容易产生二意性。
我们举个例子:
#define TABLE_MULTI(x) (x*x)
  我们用一个数字去调用它,TABLE_MULTI(10),这样看上去没有什么错误,
结果返回100,是正确的,但是如果我们用TABLE_MULTI(10+10)去调用的话,
我们期望的结果是400,而宏的调用结果是(10+10*10+10),结果是120,这显
然不是我们要得到的结果。避免这些错误的方法,一是给宏的参数都加上括号。

#define TABLE_MULTI(x) ((x)*(x))
 
  这样可以确保不会出错,但是,即使使用了这种定义,这个宏依然有可能
出错,例如使用TABLE_MULTI(a++)调用它,他们本意是希望得到(a+1)*(a+1)的
结果,而实际上呢?我们可以看看宏的展开结果: (a++)*(a++),如果a的值是
4,我们得到的结果是5*6=30。而我们期望的结果是5*5=25,这又出现了问题。
事实上,在一些C的库函数中也有这些问题。例如: Toupper(*pChar++)就会对
pChar执行两次++操作,因为Toupper实际上也是一个宏。

  我们可以看到宏有一些难以避免的问题,怎么解决呢?
 
  下面就是用我要介绍的内联函数来解决这些问题,我们可以使用内联函数
来取代宏的定义。而且事实上我们可以用内联函数完全取代预处理宏。

  内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是
通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时
候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开
销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一
些问题。
  我们可以用Inline来定义内联函数,不过,任何在类的说明部分定义的函
数都会被自动的认为是内联函数。

  下面我们来介绍一下内联函数的用法。
 
  内联函数必须是和函数体申明在一起,才有效。像这样的申明
Inline Tablefunction(int I)是没有效果的,编译器只是把函数作为普通的函
数申明,我们必须定义函数体。

Inline tablefunction(int I) {return I*I};
 
  这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调
用。但是执行速度确比一般函数的执行速度要快。

  我们也可以将定义在类的外部的函数定义为内联函数,比如:
因此,
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 内联函数inline与宏定义深入解析
  • 浅谈内联函数与宏定义的区别详解
  • 深入探讨:宏、内联函数与普通函数的区别

相关文章

  • 2017-05-28使用C++的string实现高精度加法运算的实例代码
  • 2017-05-28C语言辗转相除法求2个数的最小公约数
  • 2017-05-28浅析C++中memset,memcpy,strcpy的区别
  • 2017-05-28C语言中操作进程信号的相关函数使用详解
  • 2017-05-28交换两个文本内容的C语言代码
  • 2017-05-28详解C++编程中的静态成员与可变数据成员
  • 2017-05-28C++运算符重载 成员函数与友元函数详解
  • 2017-05-28C语言中网络地址与二进制数之间转换的函数小结
  • 2017-05-28利用C语言实现顺序表的实例操作
  • 2017-05-28关于C/C++中的side effect(负效应)和sequence point(序列点)

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C++基础学生管理系统
    • C/C++指针和取地址的方法
    • C语言实现最大间隙问题实例
    • C++中四种加密算法之AES源代码
    • 深入解析最长公共子串
    • 详谈c++11 final与override说明符
    • 如何判断一个数是否为4的幂次方?若是,并判断出来是多少次方?
    • C语言 以字符串的形式读写文件详解及示例代码
    • 解析C++中构造函数的默认参数和构造函数的重载
    • C++多继承同名隐藏实例详细介绍

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有