描述一下函数式宏定义函数的运算与普通函数有什么区别

相关文章推荐
要写好C语言,漂亮的宏定义是非常重要的。宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等。
  在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成...
http://www.jb51.net/article/41869.htm
尽管函数式宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧、传参、...
要写好C语言,漂亮的宏定义是非常重要的。宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等。
  在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成...
昨天笔试问的,不会…..
在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成为宏定义。那么究竟是用函数好,还是宏定义好?这就要求我们对二者进行合理的取舍。宏...
一、结构体中可以定义一般的宏定义
如:struct aaa
#define STATUS_1 100
#define STATUS_2 200
#define STATUS_3...
直接调用即可。如下示例:
#define sum(b,c){int d=0;d=b+c;printf("两者的和:%d\n",d);}
int main()
一 安装mssql模块
npm install mssql
二 封装连接数据库代码
/*日17:02:15
mssql模块简...
要写好C语言,漂亮的宏定义是非常重要的。宏定义可以帮助我们防止出错,提高代码的可移植性和可读性等。
  在软件开发过程中,经常有一些常用或者通用的功能或者代码段,这些功能既可以写成函数,也可以封装成...
在C及C++语言中允许用一个标识符来表示一个字符串,称为宏,该字符串可以是常数、表达式、格式串等。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。...
在C及C++语言中允许用一个标识符来表示一个字符串,称为宏,该字符串可以是常数、表达式、格式串等。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。...
他的最新文章
讲师:董晓杰
讲师:姚远
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)内联函数的执行过程与带参数宏定义很相似,但参数的处理不同。带参数的宏定义并不对参数进行运算,而是直接替换;内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数。
&&&&内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定;而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患。
&&&&使用内联函数时,应注意以下问题:
&&&&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};
  这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调用。但是执行速度确比一般函数的执行速度要快。
  我们也可以将定义在类的外部的函数定义为内联函数,比如:
Class TableClass{
 Private:
  Int I,j;
  Int add() { return I+j;};
  Inline int dec() { return I-j;}
  Int GetNum();
inline int tableclass::GetNum(){
  上面申明的三个函数都是内联函数。在C++中,在类的内部定义了函数体的
函数,被默认为是内联函数。而不管你是否有inline关键字。
  内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的
类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我
们类成员的数据了。
&&&&对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把
这些读写成员函数定义成内联函数的话,将会获得比较好的效率。
Class sample{
 Private:
  Int nT
  Int readtest(){ return nT}
 Void settest(int I) {nTest=I;}
  当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如
果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式
调用函数。这样,内联函数就和普通函数执行效率一样了。
/*这一系列文章《C++ Tips》是公司Code Committee专家会推荐工程师看的,感觉很好,拿出来与大家共同提高。并不
是知道多少会使人与人产生差别,真正的差别在于你能做到多少。
很多程序员不知道C中的&宏&到底是什么意思?特别是当宏有参数的时候,经常把宏和函数混淆。我想在这里我还是
先讲讲&宏&,宏只是一种定义,他定义了一个语句块,当程序编译时,编译器首先要执行一个&替换&源程序的动作
,把宏引用的地方替换成宏定义的语句块,就像文本文件替换一样。这个动作术语叫&宏的展开&。使用宏是比较&危
险&的,因为你不知道宏展开后会是什么一个样子。例如下面这个宏:
&&&#define MAX(a, b) a&b?a:b
当我们这样使用宏时,没有什么问题: MAX( num1, num2 ); 因为宏展开后变成 num1&num2?num1:num2;。 但是,如
果是这样调用的,MAX( 17+32, 25+21); 呢,编译时出现错误,原因是,宏展开后变成:17+32&25+21?17+32:25+21,
Woh,这是什么啊?
所以,宏在使用时,参数一定要加上括号,上述的那个例子改成如下所示就能解决问题了。
&&&#define MAX( (a), (b) ) (a)&(b)?(a)b)
即使是这样,也不这个宏也还是有Bug,因为如果我这样调用 MAX(i++,j++); , 经过这个宏以后,i和j都被累加了两次,这绝不是我们想要的。所以,在宏的使用上还是要谨慎考虑,因为宏展开是的结果是很难让人预料的。而且虽然,宏的执行很快(因为没有函数调用的开销),但宏会让源代码澎涨,使目标文件尺寸变大,(如:一个50行的宏,程序中有1000个地方用到,宏展开后会很不得了),相反不能让程序执行得更快(因为执行文件变大,运行时系统换页频繁
因此,在决定是用函数,还是用宏时得要小心。
C++中的内联函数定义很简单,只要在普通的函数前加一个关键字inline就可以了,除此之外和普通函数表面上没有什么区别(包括函数的调用方式),因为这样,所以在很多的C++初学者(甚至一些有C++编程经验的人) 看来,内联只是一个概念而已,其实这是对内联函数没有彻底的认识,下面我们就来谈谈内联函数和普通 函数以及和宏的区别,相信读完下面的部分,你对这三者一定有了很好的理解。
&&&&&&&内联函数和普通函数最大的区别在于内部的实现方面,而不是表面形式,我们知道普通函数在被调用时,系统首先要 跳跃到该函数的入口地址,执行函数体,执行完成后,再返回到函数调用的地方,函数始终只有一个拷贝; 而内联函数则不需要进行一个寻址的过程,当执行到内联函数时,此函数展开(很类似宏的使用),如果在 N处调用了此内联函数,则此函数就会有N个代码段的拷贝。
&&&&&&&从内联函数的调用来看,它因为少了一个寻址过程而提高了代码的执行效率,但是这是以空间的代价来换取的。
&&&&&&&声明为内联的函数,其代码段不能太长,过长,一些编译器则视为普通 函数(究竟函数体多长就超过了限制,这个好象没有规定,这个也确实不好规定,个人觉得应该视函数体的逻辑而定)。
&&&&&&下面是内联函数的声明举例:
&&&&&inline void SetVal(int a){ m_b = a};
&&&&&inline int GetVal(){ return m_b};
&&&&&从上面的例子可以看出,内联函数的声明和实现通常都会在一个文件当中(一般放在.h中就可以了)。
&&&&&下面我们再来说说内联函数与宏的区别。很多的资料上,在谈到内联函数时就说,内联函数和宏很类似,但是类似归类似,毕竟我们不能把这两者互换使用。
&&&&&这两者的相似之处在于执行时编译器对其的处理,会将其代码展开,执行完后继续下面的处理。不同之处在于宏是简单的文本替换,它不能返回值,也没有一般函数参数的概念;而内联函数则具备了普通函数的特征,如参数列表,返回值等。下面我们举个例子说明:
&&&&&1.#define COUNT(X)(X * X) // 一个计算乘积的宏
&&&&&2.inline int count(int x){return x*x} //一个计算乘积的内联函数
&&&&&printf(COUNT(3)); // 结果为 COUNT(3) ( 3 * 3) = 9;
&&&&&printf(count(3)); // 结果为 count(3){return 3*3 }=9;
&&&&&上面的例子好象不足以说明两者的区别,我们把上面的例子的调用改改,再看看结果
&&&&&printf(COUNT(2+3)); //结果为COUNT(2+3)(2+3 * 2+3) = 11
&&&&&printf(count(2+3)); //结果为count(2+3){return 5*5 ;} = 25;
&&&&&如果宏要达到乘积为25的结果,应该这样写:
&&&&&#define COUNT(X)((X)*(X))
&&&&&对应到上面的例子就是 #define COUNT(2+3)((2+3)*(2+3))
阅读(...) 评论()相关文章推荐
使用宏和内联函数都可以节省在函数调用方面所带来的时间和空间开销。二者都采用了空间换时间的方式,在其调用处进行展开:
在预编译时期,宏定义在调用处执行字符串的原样替换。在编译时期,内联函...
用内联取代宏:
1.内联函数在运行时可调试,而宏定义不可以;
2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;
3.内联函数可以访问类的成员变量,宏...
用内联取代宏:
1.内联函数在运行时可调试,而宏定义不可以;
2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;
3.内联函数可以访问类的成员变量,宏...
1. 宏代码不是函数
原文地址:/index.php/c-cplusplus/inline-vs-macro/
这个问题在苹果公司(Apple)和直觉(...
内联函数与宏定义的区别
http://softstudy./article-426333.html
『1.内联函数在运行时可调试,而宏定义不可以;2.编译器会对内联函...
block(块)元素的特点:
①总是在新行上开始;
②高度,行高以及外边距和内边距都可控制;
③宽度缺省是它的容器的100%,除非设定一个宽度。
④它可以容纳内联元素和其他块元...
在程序员面试宝典第三版的6.4中,有个问题,内联函数和宏的差别是什么?
由此,我们想到为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的...
用内联取代宏:
1.内联函数在运行时可调试,而宏定义不可以;
2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;
3.内联函数可以访问类的成员变量,宏...
普通内联函数
当我们定义了一个函数,编译器就会在内存中为其创建一个指令集,当我们调用这个函数时,程序就会跳转到该指令集处。当该函数运行完毕后,程序又会返回到原来执行调用该函数语句的下一行继续执行。假...
他的最新文章
讲师:董晓杰
讲师:姚远
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)2012年8月 C/C++大版内专家分月排行榜第三2012年7月 C/C++大版内专家分月排行榜第三
2008年9月 C/C++大版内专家分月排行榜第二2008年4月 C/C++大版内专家分月排行榜第二2008年2月 C/C++大版内专家分月排行榜第二2007年7月 C/C++大版内专家分月排行榜第二
2011年10月 C/C++大版内专家分月排行榜第三2009年1月 C/C++大版内专家分月排行榜第三2008年10月 C/C++大版内专家分月排行榜第三2008年5月 C/C++大版内专家分月排行榜第三2007年6月 C/C++大版内专家分月排行榜第三2007年5月 C/C++大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。c语言,宏定义,与函数的差别 我觉得宏定义和函数没什么差别啊, 是否可以用宏定义代替函数_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
c语言,宏定义,与函数的差别 我觉得宏定义和函数没什么差别啊, 是否可以用宏定义代替函数
.;int a(b例如..}#define a(b
我有更好的答案
每次调用执行的是同一个位置的代码,无论调用多少次。宏定义是简单的文本替换,产生的代码是替换后程序产生的代码。虽然功能近似,但函数会产生独立代码不同,简单说就是程序里每次使用宏替换后的地方都要产生类似的代码,而这些替换后产生的代码存在于程序的不同位置。宏定义不检查参数类型
采纳率:45%
x*y)这个表达式对于以上两种定义的得到的结果是不一样的而且,宏有宏的有点;y:x+y和int a(x,但是相应的就不用调用中断程序了#define a(x,y)
x&gt,y){return(x+y);}a(x+y,所以比较占存储空间,函数有函数的优点函数的优点就是占用存储空间少,缺点是每次调用函数都要调用中断程序,影响运行效率宏的优点就是直接宏展开,每次调用都要展开?x*y
但是当函数复杂的情况下,你就没法代替了哦!
首先宏定义和函数是有差别的宏定义是在编译之前处理的,不做语法检查。 这个很危险另外我要说#define a(b,c) {(b)+(c)}表示bc之合,在结果上和函数确实一样
其他1条回答
为您推荐:
其他类似问题
宏定义的相关知识
换一换
回答问题,赢新手礼包}

我要回帖

更多关于 ios 宏定义函数 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信