【重新上本科】关于“static”关键字的点滴

25 篇文章 0 订阅
18 篇文章 0 订阅

在面试的时候,考察语言基础的时候,有时候会遇到问题“static关键字的作用是什么”,以及相关的问题。这篇文章里面尽可能总结的全面一点。


对于c语言。

static可以修饰c语言的变量,表示静态变量,有个很cool的(或者和普通变量很不一样)的属性,就是他的生命周期与当前的生命周期一样。典型的场景就是:在函数中定义了static变量,在函数外面还能够引用这个变量。经常用来作计数器。这是函数内外一种通信的方式,就像全局变量一样。

引申的问题1:为什么具有这种属性?即为什么生命周期和当前程序一样。

答:普通变量分配在栈上,随着函数推出,栈清空,变量销毁;而静态变量的存储区域在程序的静态存储区,就像全局存储区、堆、栈、代码区一样,是一种程序的存储区域。这种存储区在程序load的时候被初始化,变量的生命开始,直到程序结束,才随着程序的销毁而被销毁。从存储的角度来看变量生命周期,就很显然了;其实那种“计数”特性只是一种副产品,从这个角度看是自然而然的事情。

小问题

静态存储区什么时候被初始化?

答:很多人对“编译时”和“运行时”会搞混。很容易回答在程序编译的时候,被初始化成xxx。其实是在运行时被初始化,就是在程序刚刚load的时候,确切地说是在进入main函数之前。如果没有默认值,则默认值是0x00。那么编译的时候编译器为静态变量做什么了?其实只是在符号表(记录内部变量的表格)中做了记录,如果只是声明而没有定义,则只有符号表的入口,编译的时候并不为它分配空间;反之,则分配空间并用该初始值作为它的值。

引申的问题2:静态变量和全局变量有什么区别?

答:相同的是生命周期,那有什么不同呢?这里和c对static的要求有关了。static的主要作用是控制被修饰变量(函数)的可见范围,即,只对当前文件可见,对外文件不可见。而全局变量是全局可见,全局可引用的。

例如:

在1.c文件中定义static变量,如下:
static int iStaticVariableFrmPlayCpp = 100;
在2.c文件中尝试引用它,如下:
extern int iStaticVariableFrmPlayCpp;
iStaticVariableFrmPlayCpp = 99;
cout << "the value of iStaticVariableFrmPlayCpp is: " << iStaticVariableFrmPlayCpp << endl;
编译器会报编译错误。

但是如果把1.c中的static关键字去掉,使之成为一个全局变量,则不会报错。

static还可以修饰函数,表示静态函数,也是控制函数的可见范围,即只在本文件内部可见,在文件外部不可见。

总的来说,static在c语言中的主要作用还是控制变量和函数的可见范围,能更好滴组织代码。


对于c++语言

对于c++语言,上述的约定亦然存在。不过c++之于c的最大不同,就是引入了面向对象设计,也就是有了类的概念。在类中,static又有了新的作用。

static修饰类的成员变量,则该变量是“类变量”,不属于类的某个实例。

static修饰类的成员函数,则该函数是“类函数”,不属于类的某个实例,而且只能够访问static成员变量。

引申的问题3:这是怎么做到的?其时和“引申的问题1”一样,就是c++编译器怎么做到这一点的?如果自己设计编译器,怎么支持这种特性?

答:static的这些特性记忆起来挺麻烦的哈。其实也不麻烦,关键不去记那些表面的东西,还是从底层的角度来看。答案同“引申的问题1”一样,想变量的存储区域。不论是修饰c中的变量还是修饰c++的类成员变量,这些变量最终存储在哪里?在静态存储区。静态存储区的东西,肯定不能和某个运行时生成的类实例相关联啊,静态存储区,在main函数之前就已经初始化好了,那时候什么实例都没初始化呢,如果真要关联,和谁关联?怎么关联?正因为如此,静态成员函数也只能够访问静态变量,因为也无法获知静态变量与哪个实例关联。而且,静态变量和静态函数,在编译期间就能够完全确定的,编译期间也无法获得运行期间的实例情况。


对于java语言

相比c++,java是更加面向对象的一种语言。java中所有东西都是在类中声明定义的,所以,“在c中的static的作用”,在java中并不适用。不过,在“c++中的static的作用”,在java中都适用。除此之外,java的类中还支持“static程序块儿”,就是,也没有函数签名,在class中来这么一段:

class xxx
{
     static
     {
     ......
     }
}

在类做初始化的时候,会首先执行static中的语句。static程序块儿,也只能访问static变量,更像一个没有函数签名的构造函数,可能把名字省了吧,反正大家都知道那是干啥的。


暂时总结到这里吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值