C/C++中static的关键字的理解总结(对比在C和C++中的区别和相同)

26 篇文章 15 订阅

前言

static关键字非常好用,特别是早期时候,对于C语言来说,就是靠static关键字完成封装性滴;常见的大型项目中,static用得非常多,并且static关键字也是面试时候的热门关键字之一。在C++中static关键字由于多了类,所以会在C语言的基础上扩展了一些关于类中成员用static关键字修饰的所以掌握非常重要。


一. C语言中的static关键字

0) C的static关键字的名字理解

static关键字,有人说他命名得不好?因为static翻译为中文是有安静的意思。但是,对于static关键字的使用来说,却一点都不安静,做的事情都很重要,比如修饰全局变量,和函数,使得该全局变量和函数只能在本文件中使用,不能直接的跨文件使用;修饰局部变量,使得该变量的声明周期得以延长,都是躁动的模样,强行改变别人的动向。
但我觉得它确实挺合适安静的名称的,修饰全局变量和函数时候,不能直接的跨文件使用了,就只能在本文件使用,这说明它使得全局变量和函数安安静静的呆在本文件中了,不能让别的文件访问了。
从不的角度想想这个关键字的名称其实也挺有意思的。


1) C的static关键字的两个作用

在C语言中,static关键字有两个作用:1.修饰变量,2. 修饰函数。

  • 修饰变量又分为两种:第一种修饰全局变量,第二种修饰局部变量。
  • 修饰全局变量,使得该全局变量只能在本文件中访问,不能直接的跨文件访问。(注意是直接)
  • 修饰局部变量,使得该局部变量的声明周期得以延长,不至于出了作用域就销毁。
  • 修饰函数,修饰函数使得该函数只能在本文件中访问,不能直接的跨文件访问。(注意直接)

下面仔细来讨论下如何理解两句话。

2) C的static修饰全局变量和修饰函数

satic关键字修饰全局变量和修饰函数的作用是一样的,所以放到一起讨论,都是使得他们不能够直接跨文件访问,限制他们只能在本文件访问。


首先,我们创建两个.c文件,一个为main.c,一个为test.c;文件名是什么不重要,只要他们不同名,且后缀为.c文件即可。

现在我要做一些事情,在 test.c 文件书写,下面的语句:

//test.c文件的内容
int i = 10; //全局遍历 i

在 main.c文件中书写下面的语句:

//main.c文件的内容


我要问一个问题,请问,当我编译运行时候,是否可以成功运行上面的程序?

答:是不可以的。因为 变量 i是未被定义的。看编译器的报错信息。

在这里插入图片描述


我要继续问,我明明在test.c文件中定义了int i = 10;为什么在 main.c文件中不能够访问?如何才能使得main.c文件能够访问到 test.c文件中的 i 呢?

答:首先,在main.c文件不能够访问test.c文件的原因很简单,因为编译是单独编译每一个.c文件的,很明显编译器不认识i;所以会报错。要想使得编译器认识 i, 那么就得在main.c文件中声明 i,即extern int i;这样 编译器就认识了 i,于此同时,在链接阶段,就会把test.c文件中的 i链接过来,那么就可在 main.c文件中访问到test.c的文件中的全局变量 i了。


即,我在main.c文件添加 extren int i语句,添加后:

# include<stdio.h>
extern int i; //声明全局变量
int main()
{	
	printf("%d\n", i); //声明后可以成功访问,该test.c的全局变量i = 20;
	return 0;
}

上诉编译就不报错了,这就可以成功访问的其他文件的test.c的变量 i ,即在main.c文件访问了test.c文件的 变量i.

那假如我有一种需求,那就是我不希望我的全局变量 i 能够被其他文件访问,即我就想我的全局变量 i就只能在本文件中访问 ,可以做到那?当然可以,那就是我们static关键字的作用,修饰全局变量,使得该全局变量不能够被跨文件访问,即test.c文件的全局变量 i,不能够在 main.c文件中使用。

所以,我们在 test.c添加关键字static 修饰 int i 20;添加后的test.c文件为:

//添加了 static 关键字的 test.c文件
static int i;

我们尝试,在 main.c文件中访问test.c文件中的全局变量 i,看看会发生什么事?
在这里插入图片描述
也是,无法解析的外部命令报错,这说明在链接时候,没有在main函数找到 变量 i,是因为我用static修饰了 test.c文件中的变量 i,使得该变量i,只能在test.c文件使用。


其实static,修饰函数也是和修饰全局变量一个道理,我们在 test.c文件中添加一个static 修饰的函数,去掉刚刚的 static int i;

//static int i;
static void show() //在test.c中用static修饰的函数
{
	printf("!!!!!!!!!!!");
}

我们在 main.c中也声明该函数,于此同时调用该函数,看看是否成功?
在这里插入图片描述
很明显,也是调用失败的,说明static修饰函数也可以使得该函数,不能直接够跨文件访问


但是,有一点很重要虽然,我们知道,static修饰的全局变量和全局函数不能够被跨文件访问,但是,他们却可以间接的跨文件访问.朋友门可以自行验证。

比如我提供一个非 static修饰的函数,在里面调用了 static修饰的函数,那么,我们就可以跨文件访问没有被 static 修饰的函数,从而间接访问 static 修饰的函数。

这也很好的体现了一种封装性,由于 static修饰函数,直能服务于本文件的,那么该函数接口就不会暴露出去,说明该函数相对有隐私一点,类似C++中,类的private。


3) C的static修饰局部变量

相信大家都了解static这个功能,修饰局部变量能够使得该局部变量不用出了作用域就直接直接销毁,而是能够继续存活下来,存活到整个程序从头到尾运行结束后,它才会销毁,这也说明static修饰的局部变量,当中值发生了改变,出了作用域也会保留该值。

static修饰局部变量,该局部变量是在编译期间就确定好值的了,所以必须初始化,不用等到运行时候才分配内存。

朋友们可以自行在 main.c数中定义一个局部变量,用static修饰,并且在static修饰的局部变量打一个断点,运行时候,你会发现,这个断点被跳过了,直接说明该static修饰的语句,在程序运行时候,不执行,但你监视它的值,确实存在,也就说明,该static修饰的局部变量,编译时候就确定初始值,运行时候就不执行该static修饰的局部变量啦。


4) C的static关键字总结

C 的 static 关键字修饰全局变量和修饰函数,使得该函数不能够直接的跨文件访问,但是能够间接的访问;
C 的 static 关键字修饰局部变量,该局部变量必须初始化,编译期间确定初始值,并且该局部变量的声明周期得以延长,不至于出作用域就销毁,知道程序运行结束才销毁。


二. C++中的static关键字

在C++上,由于多了类,所以C++中的关键字,不仅仅是用来修饰全局变量和函数,局部变量的,还会在此基础上(C++中static 修饰全局函数和修饰函数,局部变量依旧是一样的功能),增加了对类中 成员变量,成员函数的修饰。

其实我之前有篇文章就是关于C++中static修饰类的成员说明:static修饰类中的成员,在这里我就不多赘述啦。


三.static在C和C++的区别和相同

相同:

  1. 他们无论在C还是C++都修饰全局变量和局部变量和函数都是一样的。

区别:
3. 在C++中多了类,在类中,static修饰的成员变量只能类内声明,类外初始化,不向C中修饰变量,直接需要初始化,
4. 在C++中static修饰成员函数,该成员函数,只能使用static修饰的变量,不像C语言中的static修饰函数,可以在static函数里面使用任何类型的变量。
5. 在C++中,static修饰的成员(变量和函数),都是只保留一份,并且跟随对象的,就算你创建几百个对象,这里的static成员也就是一份数据。无论你在哪个对象改变了static成员的数据,在其他对象的static成员数据也会改变,因为就一份static的数据。


四. 总结

static关键字有超级多妙用的方法,这里只是简单的说明一下,如何正确的使用static关键字,帮助大家阅读static关键字的作用,等以后见多别人代码,用到static关键字,你就知道如何使用了。

  • 26
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呋喃吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值