IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言 内联函数 -> 正文阅读

[C++知识库]C语言 内联函数

【注:本文只讨论C语言中的内联函数,暂不谈论C++,因为C++中这块知识相对要更复杂。】

什么是内联函数

在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。
为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。
内联函数是代码被插入到调用者代码处的函数。内联函数通过避免被调用的开销来提高执行效率

采用内联函数实质是以空间换时间的做法

举例:

void myprintf(int a)
{
	printf(%d”,a);
}

int main()
{
	for(i=0;i<100;i++myprintf(i);
}

对于这个函数,在进行反复的打印i的过程中我们是不是要反复的调用myprintf()这个函数,进函数和出函数是需要时间的(入栈出栈),假设这个过程用时为4ms,而执行printf这个操作只需要2ms,那么在100次循环的过程中进出函数的时间比函数功能printf需要的时间还要长,这样很影响工作效率。于是,我们就想要如何避免进出函数的过程呢?可以声明inline这个关键字。

inline void myprintf(int a)
{
	printf(%d”,a);
}

int main()
{
	for(i=0;i<100;i++myprintf(i);
}

main函数中的myprintf(i);会直接替换成该函数主体,上面的代码在编译时实际上是这样的:

inline void myprintf(int a)
{
	printf(%d”,a);
}

int main()
{
	for(i=0;i<100;i++{
		printf(%d”,i);
	}
}

内联函数和宏定义区别

内联函数看上去和宏定义非常相似。
对于上面的例子,我们可以用宏定义实现:

#define MYPRINTF(a)  printf(“%d”,a);

int main()
{
	for(i=0;i<100;i++MYPRINTF(i);
}

效果可以说与前面使用内联的方式没多大差别。
但宏定义在某些情况下会有问题,比如:

// 返回 i 的绝对值的宏
#define abs1(i) \
         ( (i) >= 0 ? (i) : -(i) )

// 返回 i 的绝对值的内联函数
inline int abs2(int i)
{
   return i >= 0 ? i : -i;
}


int fun();

void userCode(int x)
{
   int ans;

   ans = abs1(x++);   // 错误!x 被增加两次
   ans = abs1(fun());   // 错误!fun()被调用两次

   ans = abs2(x++);     // 正确! x 被增加一次
   ans = abs2(fun());     // 正确! fun() 被调用一次
}

ans = abs1(x++); 展开是ans = ( (x++) >= 0 ? (x++) : -(x++) );
所以x++会执行2次,这可能是用户所不希望的。

内联函数,与直接的函数调用区别仅在于没有函数调用过程的消耗。保留了函数调用的特性,又提高函数的执行效率。

和宏不同的,还有内联函数的参数类型被检查,并且被正确地进行必要的类型转换。

使用内联函数注意事项

1、inline只适合函数体内代码量少的函数使用,因为每一处内联函数的调用都要复制代码,如果该函数代码量较大,将使程序的总代码量增大,消耗更多的内存空间。

2、内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。因为这样会在编译时无穷无尽地展开。

3、如果执行函数体内代码的时间,相比于函数调用的时间开销较大,那么使用内联的效率的收获会很少。比如函数内有循环,这种情况就不考虑用内联函数了。

4、关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用。

inline void Foo(int x, int y); // inline 仅与函数声明放在一起
void Foo(int x, int y)
{
}

5、对于功能复杂,内容较多的函数,即使加上inline修饰符,也不一定能作为内联函数,因为编译器会判定做优化。

关于static inline

static inline的内联函数,一般情况下不会产生函数本身的代码,而是全部被嵌入在被调用的地方。如果不加static,则表示该函数有可能会被其他编译单元所调用,所以一定会产生函数本身的代码。所以加了static,一般可令可执行文件变小。—【存疑,不确定】

static inline的内联函数,只能在本文件内调用,而没有static则可以被其他文件调用,这与static的常用方法一致。

函数的地址被使用的时候。如通过函数指针对函数进行了间接调用。这种情况下就不得不为static inline函数生成独立的汇编码,否则它没有自己的地址。

参考鸣谢:

https://blog.csdn.net/zqixiao_09/article/details/50877383

https://www.cnblogs.com/linux-bfbdxj520/p/11405474.html

https://www.jb51.net/article/41520.htm

https://blog.csdn.net/chuqierliang/article/details/48053417

https://blog.csdn.net/weixin_33895657/article/details/92037511

https://blog.csdn.net/qq_33757398/article/details/81390151

https://blog.csdn.net/weixin_30706507/article/details/96192546

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 00:01:57  更:2021-07-24 00:02:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/7 19:42:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码