inline内联函数 static静态函数 普通函数区别

本文深入探讨了内联函数与普通函数、静态函数与普通函数之间的关键区别,包括它们在实现、作用域及内存分配上的不同。内联函数通过减少调用开销提升效率,而静态函数则限制了函数的可见范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

面试时候一般只会问你区别,所有本文只说区别。

内联函数和普通函数的区别:

内联函数和普通函数最大的区别在于内部的实现方面,当普通函数在被调用时,系统首先跳跃到该函数的入口地址,执行函数体,执行完成后,再返回到函数调用的地方,函数始终只有一个拷贝; 而内联函数则不需要进行一个寻址的过程,当执行到内联函数时,此函数展开(很类似宏的使用),如果在 N处调用了此内联函数,则此函数就会有N个代码段的拷贝。

内联函数和普通函数最大的区别在于内部的实现方面,而不是表面形式,我们知道普通函数在被调用时,系统首先要 跳跃到该函数的入口地址,执行函数体,执行完成后,再返回到函数调用的地方,函数始终只有一个拷贝; 而内联函数则不需要进行一个寻址的过程,当执行到内联函数时,此函数展开(很类似宏的使用),如果在 N处调用了此内联函数,则此函数就会有N个代码段的拷贝。

静态函数和普通函数的区别:

static函数和普通函数的最大的区别在于作用域方面,static函数限定在本源码文件中,不能被本源码文件以外的代码文件调用。而普通的函数,默认是extern的,也就是说,可以被其它代码文件调用该函数。同时static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。

static函数和普通函数的最大的区别在于作用域方面,static函数限定在本源码文件中,不能被本源码文件以外的代码文件调用。而普通的函数,默认是extern的,也就是说,可以被其它代码文件调用该函数。同时static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。

补充:

1、内联函数和宏的区别?

答:为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。这种转移操作要求在转去执行前要保存现场并记忆执行的地址,转回后要恢复现场,并按原来保存地址继续执行。因此,函数调用要有一定的时间和空间方面的开销,于是将影响其效率。而宏只是在预处理的地方把代码展开,不需要额外的空间和时间方面的开销,所以调用一个宏比调用一个函数更有效率。

但是宏也有很多的不尽人意的地方。比如,宏不能访问对象的私有成员,还有宏的定义很容易产生二意性。我们举个例子:

#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实际上也是一个宏。

内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。

2、到底什么是内联函数?

GCC中的inline函数可以相当于在一个普通的全局函数加上inline属性。inline关键字仅仅是建议编译器在编译的时候做内联展开处理,而不是强制在gcc编译器中,如果吧编译选项设置为负无穷,即使是inline函数也不会被内联展开,除非设置了强制内联展开的属性(attribute((always_inline)))。

3、静态函数有什么特点?

静态函数又称为内部函数。在C/C++中,定义的函数默认都是全局的(相对于多个文件的源程序)。而在函数的前面加上static关键字可以改变函数的作用域,即将函数的作用域限定在含有此函数的定义所在的文件,在其他文件中不可以使用此函数。

静态函数作用呢:1,起隐藏作用,静态函数只能在本文件中被访问,而不能被除此文件外的其他文件所使用。2,使用静态函数可以在其他文件中定义同名的函数,而不用考虑会出现名字冲突或者冲定义的错误。

4、静态函数的内存分配
static只会改变(限制)函数的作用域,而不会像静态变量那样改变变量的存储位置。static的函数和普通函数的内存存储区域以及内存分配方式是相同的。

静态内联函数static inline)和普通内联函数inline)在 C++ 中有一些关键的区别: 1. **预编译阶段**: - 普通内联函数:编译器在看到函数调用时可能会决定将其替换为实际的代码,这个过程称为“内联”。如果内联失败或频繁发生,编译器不会强制进行内联,而是会在运行时根据情况动态决定。 - 静态内联函数:即使编译器没有选择内联,链接器也会确保内联代码在整个程序中的所有实例都被替换,因为它们是静态链接的。 2. **链接次数**: - 普通内联函数:每个函数实例都有自己的副本,所以如果你在一个头文件中声明并定义了一个内联函数,每个使用它的源文件都会有一个独立的内联版本。 - 静态内联函数:全局只有一个拷贝,这意味着当你在多个地方包含同一个头文件时,编译器只会为整个程序生成一份内联代码。 3. **可见性和重载**: - 普通内联函数内联函数可以在头文件中定义,用于重载,但通常建议避免这样做,以防链接器冲突。 - 静态内联函数:由于链接器保证只有一份内联代码,所以可以直接在头文件中定义,同时支持内联函数的重载。 4. **编译器行为**: - 普通内联函数:编译器可以根据优化级别、内存大小限制等因素灵活地选择是否内联。 - 静态内联函数:虽然编译器可以选择不内联,但在大多数情况下,它会尽可能地进行内联,除非遇到性能或其他限制。 总的来说,静态内联函数提供了更严格的内联保证和更好的空间效率,但可能会增加编译时间,特别是对于大型项目和复杂代码。而普通内联函数提供了一定程度的灵活性,适合那些不确定是否会被内联的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值