C语⾔中inline和extern关键字⽤法
inline⽤法
内联函数
在C语⾔中,如果⼀些函数被频繁调⽤,不断地有函数⼊栈,即函数栈,会造成栈空间或栈内存的⼤量消耗。
为了解决这个问题,特别的引⼊了inline修饰符,表⽰为内联函数。
栈空间就是指放置程序代码的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,假如频繁⼤量的使⽤就会造成因栈空间不⾜所造成的程序出错的问题,函数的死循环递归调⽤的最终结果就是导致栈内存空间枯竭。
代码⽤例
#include <stdio.h>
//函数定义为inline即:内联函数
inline char*dbtest(int a)
{
return(i %2>0)?"奇":"偶";
}
int main()
{
int i =0;
for(i=1; i <100; i++)
{
printf("i:%d 奇偶性:%s /n", i,dbtest(i));
}
}
其实在内部的⼯作就是在每个for循环的内部任何调⽤dbtest(i)的地⽅都换成了(i%2>0)?“奇”:“偶”,这样就避免了频繁调⽤函数对栈内存重复开辟所带来的消耗。
内联函数编程风格
1、关键字inline 必须与函数定义体放在⼀起才能使函数成为内联,仅将inline 放在函数声明前⾯不起任何作⽤。
如下风格的函数Foo 不能成为内联函数:
inline void Foo(int x,int y);// inline 仅与函数声明放在⼀起
void Foo(int x,int y)
{
}
⽽如下风格的函数Foo 则成为内联函数:
void Foo(int x,int y);
inline void Foo(int x,int y)// inline 与函数定义体放在⼀起
{
}
所以说,inline 是⼀种 “⽤于实现的关键字” ,⽽不是⼀种“⽤于声明的关键字”。⼀般地,⽤户可以阅读函数的声明,但是看不到函数的定义。尽管在⼤多数教科书中内联函数的声明、定义体前⾯都加了inline 关键字,但我认为inline 不应该出现在函数的声明中。这个细节虽然不会影响函数的功能,但是体现了⾼质量C++/C 程序设计风格的⼀个基本原则:声明与定义不可混为⼀谈,⽤户没有必要、也不应该知道函数是否需要内联。
2、inline的使⽤是有所限制的
inline只适合函数体内代码简单的函数数使⽤,不能包含复杂的结构控制语句例如while、switch,并且内联函数本⾝不能是直接递归函数(⾃⼰内部还调⽤⾃⼰的函数)。
3、慎⽤内联
内联能提⾼函数的执⾏效率,为什么不把所有的函数都定义成内联函数?如果所有的函数都是内联函数,还⽤得着“内联”这个关键字吗?
内联是以代码膨胀(复制)为代价,仅仅省去了函数调⽤的开销,从⽽提⾼函数的执⾏效率。如果执⾏函数体内代码的时间,相⽐于函数调⽤的开销较⼤,那么效率的收获会很少。另⼀⽅⾯,每⼀处内联函数的调⽤都要复制代码,将使程序的总代码量增⼤,消耗更多的内存空间。
以下情况不宜使⽤内联:
(1)如果函数体内的代码⽐较长,使⽤内联将导致内存消耗代价较⾼。
(2)如果函数体内出现循环,那么执⾏函数体内代码的时间要⽐函数调⽤的开销⼤。
⼀个好的编译器将会根据函数的定义体,⾃动地取消不值得的内联(这进⼀步说明了inline 不应该出现在函数的声明中)。
4、将内联函数放在头⽂件⾥实现是合适的,省却你为每个⽂件实现⼀次的⿇烦
⽽所以声明跟定义要⼀致,其实是指,如果在每个⽂件⾥都实现⼀次该内联函数的话,那么,最好保证每个定义都是⼀样的,否则,将会引起未定义的⾏为。
extern⽤法
利⽤关键字extern,可以在⼀个⽂件中引⽤另⼀个⽂件中定义的变量或者函数,下⾯就结合具体的实例,分类说明⼀下。
⼀、引⽤同⼀个⽂件中的变量
#include<stdio.h>
int func();
int main()
{
func();//1
printf("%d",num);//2
return0;
}
switch的用法c语言int num =3;
int func()
{
printf("%d\n",num);
}
如果按照这个顺序,变量 num在main函数的后边进⾏声明和初始化的话,那么在main函数中是不能直接引⽤num这个变量的,因为当编译器编译到这⼀句话的时候,不到num这个变量的声明,但是在func函数中是可以正常使⽤,因为func对num的调⽤是发⽣在num的声明和初始化之后。
如果我不想改变num的声明的位置,但是想在main函数中直接使⽤num这个变量,怎么办呢?可以使⽤extern这个关键字。像下⾯这⼀段代码,利⽤extern关键字先声明⼀下num变量,告诉编译器num这个变量是存在的,但是不是在这之前声明的,你到别的地⽅吧,果然,这样就可以顺利通过编译啦。但是你要是想欺骗编译器也是不⾏的,⽐如你声明了extern int num;但是在后⾯却没有真正的给出num变量的声明,那么编译器去别的地⽅了,但是没到还是不⾏的。
下⾯的程序就是利⽤extern关键字,使⽤在后边定义的变量。
int main()
{
func();//1
extern int num;
printf("%d",num);//2
return0;
}
int num =3;
int func()
{
printf("%d\n",num);
}
⼆、引⽤另⼀个⽂件中的变量
如果extern这个关键字就这点功能,那么这个关键字就显得多余了,因为上边的程序可以通过将num变量在main函数的上边声明,使得在main函数中也可以使⽤。
extern这个关键字的真正的作⽤是引⽤不在同⼀个⽂件中的变量或者函数。
main.c
#include<stdio.h>
int main()
{
extern int num;
printf("%d",num);
return0;
}
b.c
#include<stdio.h>
int num =5;
void func()
{
printf("fun in a.c");
}
例如,这⾥b.c中定义了⼀个变量num,如果main.c中想要引⽤这个变量,那么可以使⽤extern这个关键字,注意这⾥能成功引⽤的原因是,num这个关键字在b.c中是⼀个全局变量,也就是说只有当⼀个变量是⼀个全局变量时,extern变量才会起作⽤。
另外,extern关键字只需要指明类型和变量名就⾏了,不能再重新赋值,初始化需要在原⽂件所在处
进⾏,如果不进⾏初始化的话,全局变量会被编译器⾃动初始化为0。
像这种写法是不⾏的。
extern int num=4;
但是在声明之后就可以使⽤变量名进⾏修改了。
{
extern int num;
num=1;
printf("%d",num);
return0;
}
使⽤include将另⼀个⽂件全部包含进去可以引⽤另⼀个⽂件中的变量,但是这样做的结果就是,被包
含的⽂件中的所有的变量和⽅法都可以被这个⽂件使⽤,这样就变得不安全,如果只是希望⼀个⽂件使⽤另⼀个⽂件中的某个变量还是使⽤extern关键字更好。
引⽤另⼀个⽂件中的函数
extern除了引⽤另⼀个⽂件中的变量外,还可以引⽤另⼀个⽂件中的函数,引⽤⽅法和引⽤变量相似。
mian.c
#include<stdio.h>
int main()
{
extern void func();
func();
return0;
}
b.c
#include<stdio.h>
const int num=5;
void func()
{
printf("fun in a.c");
}
这⾥main函数中引⽤了b.c中的函数func。因为所有的函数都是全局的,所以对函数的extern⽤法和对全局变量的修饰基本相同,需要注意的就是,需要指明返回值的类型和参数。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论