define and inline

  1. 我们编写一个求一个数平方的运算,

    #define宏定义实现如下:

    #define SQUARE1(X) X*X

    inline内联函数实现如下:

    inline int SQUARE2(int X){return X*X;}

    END

步骤2——定义所需变量

  1. 1

    首先定义所需变量:

    int a=5,b=5;

    int s1=0,s2=0;

    定义a和b值相同,其中a代入#define测试,b代入inline测试;

    s1存储#define结果,s2存储inline结果。

    END

步骤3——测试#define和inline

  1. 1

    测试1:编写如下代码:

    s1 = SQUARE1(a);

    cout<<"s1= "<<s1<<endl;

    s2 = SQUARE2(b);

    cout<<"s2= "<<s2<<endl;

    结果输出:

    s1= 25

    s2= 25

    可以看到两者输出结果相同,分析:

    s1 = SQUARE1(a);等同于

    s1 = a*a;

    所以s1等于a的平方25;

    s2 = SQUARE2(b);等同于

    先进行SQYARE2()函数调用,b(5)作为实参传递,函数返回5*5的值,然后再把该值赋给s2,所以s2同样等于25

  2. 2

    测试2:编写如下代码:

    s1 = SQUARE1(a+b);

    cout<<"s1= "<<s1<<endl;

    s2 = SQUARE2(a+b);

    cout<<"s2= "<<s2<<endl;

    结果输出:

    s1= 35

    s2= 100

    可以看到两者输出结果不相同,分析:

    s1 = SQUARE1(a+b);等同于

    s1 = a+b*a+b;

    可以看到#define仅仅进行单纯的替换,那么由于运算符存在优先级,得到

    s1 = 5+25+5=35;

    s2 = SQUARE2(a+b);等同于

    先进行SQYARE2()函数调用,a+b的结果10作为实参传递,函数返回10*10的值,然后再把该值赋给s2,所以s2同样等于100。

    这里涉及到程序顺序点的知识,对应这里就是#define只进行简单替换,整个SQUARE1(a+b)后面是顺序点,而对于inline定义的SQUARE2(a+b)来说,存在两个顺序点,第一个在a+b后,第二个在整个SQUARE2(a+b)后,也就是说程序会先进行a+b的运算(顺序点1),把得到的结果再参与SQUARE2()内部代码运算(顺序点2)。

  3. 3

    可能有人会说,把#define坐入如下改进就可以解决问题了:

    #define SQUARE1(X) ((X)*(X))

    的确这样上面的问题就解决了,但会不会还存在其他问题呢?

    看下面的测试3:

  4. 4

    测试3:编写如下代码:

    s1 = SQUARE1(a++);

    cout<<"s1= "<<s1<<endl;

    cout<<"a = "<<a<<endl;

    s2 = SQUARE2(b++);

    cout<<"s2= "<<s2<<endl;

    cout<<"b = "<<b<<endl;

    结果输出:

    s1= 25

    a = 7

    s2= 25

    b = 6

    可以看到两者输出结果不尽相同,分析:

    s1 = SQUARE1(a++);等同于

    s1 = a++*a++;由于后缀++是先使用后递增,所以

    s1 = 5*5 = 25

    然后a两次递增得到a=7

    s2 = SQUARE2(b++);等同于

    先进行SQUARE2()函数调用,同样由于后缀++先使用后递增的原则,b的初始值5作为实参传递,函数返回5*5的值,然后再把该值赋给s2,所以s2等于25;

    然后b++得到b=6

    参照前面介绍的顺序点的知识,就会发现在这种情况下,#define会将参数递增两次,而inline则将参数递增一次,即使进行第三步中的改进此问题依然存在,详见下面实测截图

  5. 5

    实测结果如下图:

    #define SQUARE1(X) X*X

  6. 6

    #define SQUARE1(X) ((X)*(X))

    可以看到测试2的问题得到解决,但测试3问题依然存在

    END

注意事项

  • 如果使用C语言的宏执行类似函数的操作,应考虑将它们转换为C++内联函数
时间: 2024-10-08 10:16:35

define and inline的相关文章

define 与 inline

#define和inline 的区别 define:定义预编译时处理的宏:  只进行简单的字符替换,无类型检测 typedef:定义类型别名 用于处理复杂类型  例: typedef int A:  则:A a: //定义a为int inline: 内联函数对编译器提出建议,是否进行宏替换,编译器有权拒绝 既为提出申请,不一定会成功 static一.产生背景 引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉

#define\const\inline的区别与联系

总结: const用于代替#define一个固定的值,inline用于代替#define一个函数.是#define的升级版,为了消除#define的缺陷. #define和inline 的区别 define:定义预编译时处理的宏:  只进行简单的字符替换,无类型检测 typedef:定义类型别名 用于处理复杂类型  例: typedef int A:  则:A a: //定义a为int inline: 内联函数对编译器提出建议,是否进行宏替换,编译器有权拒绝 既为提出申请,不一定会成功 stat

define和inline关键字比较

这里我们学习一下define和inline关键字的用法,以及它们的区别. define:定义预编译时处理的宏,只是简单的字符串替换,无类型检查. inline:1.inline关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义,编译阶段完成.  2.内联函数要做类型安全检查,inline是指嵌入代码,在调用函数的地方不是跳转,而是把代码直接写到那里去,对于短小的函数来说,inline函数可以得到一定效率的提升,和c时代的宏函数相比,inline函数更加安全可靠,这个

gcc 编译器对 inline 函数的支持

C99版的C语言引入了inline关键字开始支持inline 函数,在这之前传统的C语言(C89)是没有inline 关键字的,也不支持inline 函数.不过大多数 C89 的编译器都将inline作为一种附加特性早早的就加进去了.gcc 也不例外,不过gcc增加inline特性时C99还没定型,gcc中inline 的语意与C99也有些许的区别.这里就主要说说gcc 中的inline 特性. 另外,本文只讨论C语言,C++标准中很早就支持inline,不过inline的语意C和C++ 是有细

C++关键字 inline

在C&C++中 一.inline关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义. 表达式形式的宏定义一例: #define ExpressionName(Var1,Var2) ((Var1)+(Var2))*((Var1)-(Var2)) 取代这种形式的原因如下: 1. C中使用define这种形式宏定义的原因是因为,C语言是一个效率很高的语言,这种宏定义在形式及使用上像一个函数,但它使用预处理器实现,没有了参数压栈,代码生成等一系列的操作,因此,效率很高,这是

gcc标准,c++中的inline

1. GCC的inlinegcc对C语言的inline做了自己的扩展,其行为与C99标准中的inline有较大的不同. 1.1. static inlineGCC的static inline定义很容易理解:你可以把它认为是一个static的函数,加上了inline的属性.这个函数大部分表现和普通的static函数一样,只 不过在调用这种函数的时候,gcc会在其调用处将其汇编码展开编译而不为这个函数生成独立的汇编码.除了以下几种情况外: 函数的地址被使用的时候.如通过函数指针对函数进行了间接调用.

static inline和inline的区别——stm32实测

参考:http://armbbs.cn/forum.php?mod=viewthread&tid=95190&extra=page%3D1 对于内联函数,不能像普通函数那样,直接在.h文件里面声明下,源文件里面定义下,然后其他C文件就可以调用. 而加上static的前缀后,就解决了这个问题.以CMSIS软件包为例,就全部在头文件里面定义好,并加上了STATIC,这样其他文件就都可以调用了 #define __INLINE                               inli

bzoj1150 [CTSC2007]数据备份

Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的乐趣.已知办公楼都位于同一条街上.你决定给这些办公楼配对(两个一组).每一对办公楼可以通过在这两个建筑物之间铺设网络电缆使得它们可以互相备份.然而,网络电缆的费用很高.当地电信公司仅能为你提供 K 条网络电缆,这意味着你仅能为 K 对办公楼(或总计2K个办公楼)安排备份.任一个办公楼

bzoj4568 [Scoi2016]幸运数字

Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游览 A 国.旅行者计划乘飞机降落在 x 号城市,沿着 x 号城市到 y 号城市之间那条唯一的路径游览,最终从 y 城市起飞离开 A 国.在经过每一座城市时,游览者就会有机会与这座城市的幸运数字拍照,从而将这份幸运保存到自己身上.然而,幸运是不能简单叠加的,这一点游览者也十分清楚.他们迷