美文网首页
内联函数也可以用来代替宏

内联函数也可以用来代替宏

作者: LoveSkye | 来源:发表于2019-10-22 22:29 被阅读0次

https://blog.csdn.net/qq_36708941/article/details/76855575

使用宏的一个经典例子是求一个数的平方,如下所示:

#include <iostream>

using namespace std;

#define SQ(y) y*y

int main(){

    int n, sq;

    cin>>n;

    sq = SQ(n);

    cout<<sq<<endl;

    return 0;

}

运行结果:

9↙

81

从表面上看这个宏定义是正确的,但当我们将宏调用 SQ(n) 换成 SQ(n+1) 后,就会出现意想不到的状况:

#include <iostream>

using namespace std;

#define SQ(y) y*y

int main(){

    int n, sq;

    cin>>n;

    sq = SQ(n+1);

    cout<<sq<<endl;

    return 0;

}

运行结果:

9↙

19

我们期望的结果是 100,但这里却是 19,两者大相径庭。这是因为,宏展开仅仅是字符串的替换,不会进行任何计算或传值,上面的 sq = SQ(n+1); 在宏展开后会变为sq = n+1*n+1;,这显然是没有道理的。

如果希望得到正确的结果,应该将宏定义改为如下的形式:

#define SQ(y) (y)*(y)

这样宏调用 sq = SQ(n+1); 就会展开为 sq = (n+1)*(n+1);,得到的结果就是 100。

如果你认为这样就万事大吉了,那下面的结果会让你觉得考虑不周:

#include <iostream>

using namespace std;

#define SQ(y) (y)*(y)

int main(){

    int n, sq;

    cin>>n;

    sq = 200 / SQ(n+1);

    cout<<sq<<endl;

    return 0;

}

运行结果:

9↙

200

之所以会出现这么奇怪的结果,是因为宏调用 sq = 200 / SQ(n+1); 会被展开为sq = 200 / (n+1) * (n+1);,当 n 被赋值 9 后,相当于 sq = 200 / 10 * 10,结果显然是 200。

要想得到正确的结果,还应该对宏加以限制,在两边增加 ( ),如下所示:

#define SQ(y) ( (y)*(y) )

这样宏调用 sq = 200 / SQ(n+1); 就会展开为sq = 200 / ( (n+1) * (n+1) );,得到的结果就是 2。

说了这么多,我最终想强调的是,宏定义是一项 “细思极密” 的工作,一不小心就会踩坑,而且不一定在编译和运行时发现,给程序埋下隐患。

如果我们将宏替换为内联函数,情况就没有那么复杂了,程序员就会游刃有余,请看下面的代码:

#include <iostream>

using namespace std;

inline int SQ(int y){ return y*y; }

int main(){

    int n, sq;

    cin>>n;

    //SQ(n)

    sq = SQ(n);

    cout<<sq<<endl;

    //SQ(n+1)

    sq = SQ(n+1);

    cout<<sq<<endl;

    //200 / SQ(n+1)

    sq = 200 / SQ(n+1);

    cout<<sq<<endl;

    return 0;

}

运行结果:

9↙

81

100

2

看,一切问题迎刃而解!发生函数调用时,编译器会先对实参进行计算,再将计算的结果传递给形参,并且函数执行完毕后会得到一个值,而不是得到一个表达式,这和简单的字符串替换相比省去了很多麻烦,所以在编写 C++ 代码时我推荐使用内联函数来替换带参数的宏。

和宏一样,内联函数可以定义在头文件中(不用加 static 关键字),并且头文件被多次#include 后也不会引发重复定义错误。这一点和非内联函数不同,非内联函数是禁止定义在头文件中的,它所在的头文件被多次#include 后会引发重复定义错误。

内联函数在编译时会将函数调用处用函数体替换,编译完成后函数就不存在了,所以在链接时不会引发重复定义错误。这一点和宏很像,宏在预处理时被展开,编译时就不存在了。从这个角度讲,内联函数更像是编译期间的宏。

相关文章

  • 内联函数也可以用来代替宏

    https://blog.csdn.net/qq_36708941/article/details/7685557...

  • 内联函数与宏定义

    内联函数与宏定义 在C中,常用预处理语句#define来代替一个函数定义。例如:#define MAX(a,b) ...

  • C/C++知识点分享(29)

    1.宏与内联函数的区别 解析:内联函数和宏都是在程序出现的地方展开,内联函数不是通过函数调用实现的,是在调用该函数...

  • C/C++知识点分享(12)

    1.内联函数和宏的差别? 答:内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函...

  • 宏和内联函数

    宏不是函数,但是用起来像函数,预处理器用复制宏代码的方式代替函数的调用,省区函数压栈过程,提高了效率。内联函数是函...

  • 王道程序员求职宝典(十)函数,栈与队列

    函数 参数传递值传递指针传递引用传递指针引用*& 内联函数成员函数内联普通函数内联宏定义 默认参数从右向左设定默认...

  • NS_INLINE 内联函数

    1 内联函数与宏定义 C++ 语言支持函数内联,其目的是为了提高函数的执行效率(速度)。在C程序中,可以用宏代码提...

  • 宏定义函数与内联函数

    宏定义函数 在c程序中,可以使用宏定义函数代替简单的函数,这样提高程序效率,预处理器用复制宏代码的方式代替函数调用...

  • 内联函数,重载函数,参数默认的函数

    内联函数 内联函数和宏差不多,要是时间不要空间;关键字inline。内联函数中,不能有复杂的控制语句,比如if或f...

  • 第九章 内联函数

    简介:C++中预处理器宏存在的问题,在C++中如何用内联函数解决这些问题以及使用内联函数的方针和内联函数的工作机制...

网友评论

      本文标题:内联函数也可以用来代替宏

      本文链接:https://www.haomeiwen.com/subject/wgwcvctx.html