宏函数和普通函数(宏函数的定义)
本文目录
- 宏函数的定义
- 比较函数式宏定义和普通函数的区别
- Excel宏与函数的本质区别
- c语言宏定义问题 宏定义不是可以实现和函数相同功能 那为什么还要分函数和宏定义两种功能
- 宏和函数的区别是什么
- C语言中宏函数跟自定义的函数有什么区别
- C语言类函数宏和一般函数的区别
- 函数式宏定义和普通函数的区别
宏函数的定义
【定义】:宏(计算机术语):计算机科学里的宏(Macro),是一种批量批处理的称谓。一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。这种替换在预编译时进行,称作宏展开。函数(计算机术语):为实现某一特殊目的单独编写存放的小程序块,也可称为方法。【纠错】:宏是宏,函数是函数,这是两个不同的概念,一般我们只说宏就可以了。
比较函数式宏定义和普通函数的区别
不同。虽然功能近似,但函数会产生独立代码,每次调用执行的是同一个位置的代码,无论调用多少次。宏定义是简单的文本替换,产生的代码是替换后程序产生的代码,简单说就是程序里每次使用宏替换后的地方都要产生类似的代码,而这些替换后产生的代码存在于程序的不同位置。宏定义不检查参数类型,仅仅是简单的文本替换
Excel宏与函数的本质区别
没有本质区别,都是VBA编写的程序,略有细微的差异:宏是SUB,过程,不返回结果;函数是FUNCTION,可以返回参数,可以工作表调用。
c语言宏定义问题 宏定义不是可以实现和函数相同功能 那为什么还要分函数和宏定义两种功能
我们以下面两行代码为例,展开描述:函数式宏定义:#define MAX(a,b) ((a)》(b)?(a):(b))普通函数 :MAX(a,b) { return a》b?a:b;}(1)函数式宏定义的参数没有类型,预处理器只负责做形式上的替换,而不做参数类型检查,所以传参时要格外小心。(2)调用真正函数的代码和调用函数式宏定义的代码编译生成的指令不同。如果MAX是个普通函数,那么它的函数体return a 》 b ? a : b; 要编译生成指令,代码中出现的每次调用也要编译生成传参指令和call指令。而如果MAX是个函数式宏定义,这个宏定义本身倒不必编译生成指令,但是代码中出现的每次调用编译生成的指令都相当于一个函数体,而不是简单的几条传参指令和call指令。所以,使用函数式宏定义编译生成的目标文件会比较大。(3)函数式宏定义要注意格式,尤其是括号。如果上面的函数式宏定义写成 #define MAX(a, b) (a》b?a:b),省去内层括号,则宏展开就成了k = (i&0x0f》j&0x0f?i&0x0f:j&0x0f),运算的优先级就错了。同样道理,这个宏定义的外层括号也是不能省的。若函数中是宏替换为 ++MAX(a,b),则宏展开就成了 ++(a)》(b)?(a):(b),运算优先级也是错了。(4)若函数参数为表达式,则普通函数的调用与函数式宏定义的替换过程是不一样的。普通函数调用时先求实参表达式的值再传给形参,如果实参表达式有Side Effect,那么这些SideEffect只发生一次。例如MAX(++a, ++b),如果MAX是普通函数,a和b只增加一次。但如果MAX函数式宏定义,则要展开成k = ((++a)》(++b)?(++a):(++b)),a和b就不一定是增加一次还是两次了。所以若参数是表达式,替换函数式宏定义时一定要仔细看好。5)函数式宏定义往往会导致较低的代码执行效率。看下面一段代码:复制代码代码如下:int a={9,3,5,2,1,0,8,7,6,4};int max(n){ return n==0?a,max(n-1));}int main(){ max(9); return 0;}若是普通函数,则通过递归,可取的最大值,时间复杂度为O(n)。但若是函数式宏定义,则宏展开为( a:max(n-1) ),其中max(n-1)被调用了两遍,这样依此递归下去,时间复杂度会很高。尽管函数式宏定义和普通函数相比有很多缺点,但只要小心使用还是会显著提高代码的执行效率,毕竟省去了分配和释放栈帧、传参、传返回值等一系列工作,因此那些简短并且被频繁调用的函数经常用函数式宏定义来代替实现。
宏和函数的区别是什么
1/ 宏只是预编译时一一展开,没有类型检查,可能产生二义性;同时宏写的函数不容易直观看懂。#define MAX(a,b) ( (a)《(b)?(b):(a) )2/ 内联函数并不总是被内联,inline对于编译器不是强制性的,缟译器根椐内联函数代码行数决定是否参于内联,从编译后生成的目标代码大小就能看出到底编译器是否真的内联了,调用1次和调用2次目标代码空间是不一样的。template《typename T》inline void Count( const T& a, const T& b ){ printf("always_inline?"); printf("always_inline?"); printf("always_inline?"); printf("always_inline?"); int c = a + b;}3/ 那么我们就强置内联好了,编译时会出现什么问题呢?template《typename T》inline __attribute__((always_inline)) void Count( const T& a,const T& b ){ printf("always_inline?"); printf("always_inline?"); printf("always_inline?"); int c = a + b;}Test.h:25: sorry, unimplemented: inlining failed in call to ’void Count(const T&, const T&) ’: function body not available// 说明模板不能参于强制内联4/ 去掉模板声明,采取强制内联是有效果的,并且随着调用次数的增加目标代码是不断增大的,说明强制内联起作用了,那它真达到宏的作用了吗?inline __attribute__((always_inline)) void Count( int a,int b ){ printf("always_inline?"); printf("always_inline?"); printf("always_inline?"); int c = a + b;}5/ 那我们改一下再和宏比较, 调用强制Count版本两次,没有报变量c被重复定义,不知道为什么? 难道可以获取到每一次调用Count的函数地址吗(实际GDB时就没有Count函数的概念)? 如果调用宏版本的Count,是会报变量c被重复定义,简单替换啦.inline __attribute__((always_inline)) void Count( int a,int b ){ printf("always_inline?"); printf("always_inline?"); printf("always_inline?"); int c = a + b;}#define Count(a,b) \ printf("always_inline?"); \ printf("always_inline?"); \ printf("always_inline?"); \ int c = a + b
C语言中宏函数跟自定义的函数有什么区别
可以把宏理解成拼字游戏,它功能很强大,但是强大到使用不好就会有副作用。C++有很多语言设施用来完全特定功能的宏,如const,inline,template,就是为了让大家少用宏。给你举个宏和函数不同的例子代码:#define max(x,y) ((x)》(y)?(x):(y))template 《class T》inline T max(T x,T y){return x》y?x:y;}看起来似乎是相同的功能,可是函数调用,毕竟会求完每一个实参的值,再传递给被调函数,即使声明了inline,在调用点展开而不发生实际的调用开销。但是你试试用这个调用宏,结果就会有问题:int i=4,j=5;int k=max(i++,j++);如果是函数调用,i==5,j==6,k==5。如果是宏的话,结果是:int k=((i++)》(j++)?(i++):(j++));你觉得会一样吗?所以,慎用宏。MFC中有很多功能是宏完成的,它太强大了,很多情况下有宏很高效,但是不容易控制。
C语言类函数宏和一般函数的区别
:在C及C++语言中允许用一个标识符来表示一个字符串,称为宏,该字符串可以是常数、表达式、格式串等。在编译预处理时,对程序中所有出现的“宏名”,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。
函数式宏定义和普通函数的区别
内联函数的执行过程与带参数宏定义很相似,但参数的处理不同。带参数的宏定义并不对参数进行运算,而是直接替换内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数。
本文相关文章:
clrscr函数功能(c语言中clrscr这个函数有什么用感觉有没有它都不影响啊)
2024年10月4日 18:50
matlab交流网站(MATLAB2015中的simulink建模后怎么得到波特图,能不能得到传递函数)
2024年9月30日 22:30
损失函数曲线(DFSS培训咨询中的质量损失函数和质量特性波动有什么关系)
2024年9月30日 16:45
求解:db2 length函数疑问?winrar64位如何破解我是在他的官网下载的
2024年9月30日 10:25
phpforeach(PHP 关于foreach函数的问题)
2024年9月30日 09:10
matlab求二元函数最小值(怎么用matlab求R内的二元函数最小值啊 可能是近似)
2024年9月29日 23:10
matlab二元隐函数绘图(matlab 隐函数求解以及绘图)
2024年9月29日 20:40
column函数的使用(EXCEL中“column”函数和“MOD”函数的用法)
2024年9月29日 04:40
replicate函数(基于python的opencv学习——copyMakeBorder()函数)
2024年9月28日 08:15
mysql查询大于某个日期(如何利用MySQL函数查询特定的日期时间)
2024年9月27日 20:30
evaluate为什么出不来结果(为什么这个有的可以出结果,有的却不能呢我套用的是=evaluate()函数求高人指点呀谢谢了)
2024年9月27日 03:45
cesium的datasource(Cesium快速上手9-Camera和Scene中的其他函数使用)
2024年9月9日 18:01
day函数是什么意思(函数DAY($A$3)*4-4 代表什么意思)
2024年9月8日 10:45
递归算法解决八皇后问题(用递归函数设计八皇后问题的回溯算法C++代码)
2024年9月8日 09:01
c语言lseek函数的用法(问一个关于lseek函数的效率问题)
2024年9月7日 14:45
更多文章:
安踏海报被指擦边,相关人员受到了什么惩罚?安踏客服回应女鞋海报被指擦边,具体是如何回应的
2024年7月18日 02:33
maven本地仓库和远程仓库(如何让 Maven 来使用 Nexus 本地仓库用来替代使用远程仓库)
2024年7月4日 23:46
iframe获取父页面元素(iframe子页怎么获取父页的window对象)
2024年7月9日 11:55
uniapp插件市场(随着HTML5的发展,三年内APP会消失吗)
2024年6月23日 05:35
oracle好学吗要学多久(成为Oracle DBA需要多少时间的学习)
2024年7月20日 07:08
vs2010下载安装(下载的VS2010是ISO格式的 怎么安装)
2024年1月29日 09:00
vulnerable词根词缀(谁给个所有英语单词联想记忆的方法)
2024年7月23日 06:56
1101的补码原码反码(11010101的原码反码和补码怎么算)
2024年7月24日 12:21
sql server两种身份验证模式(简单叙述SQL Server登录验证的两种模式的区别)
2024年7月4日 23:52
苹果14手机最新消息官方(苹果官网iphone14全系列降价了)
2024年6月9日 16:49
android系统签名静默升级(求助,,每次开机都显示android系统正在升级)
2024年7月23日 00:00
layui官网文档(国内有哪些类似Google Docs的在线文档编辑软件)
2024年7月2日 19:22