我个人对于static关键字的理解有以下几方面,不对的地方,也请大家在评论里指出来,一起学习,一起进步,,下面谈到的static关键字主要是针对C语言的。
程序运行时变量在内存中的存储位置
(1)static修饰局部变量
①局部变量的生命周期
局部变量默认是程序运行的时候,在栈中分配空间的,这样在函数结束的时候,局部变量对应的内存被释放掉。
当用static修饰局部变量的时候,static修饰的局部变量分配的空间在静态区区域(data/bss段),这样的局部变量,不会在函数调用结束的时候,把对应的空间释放掉。
②局部变量值的情况
局部变量如果没有赋值的时候,默认值为随机值(程序运行的时候,在栈中开辟空间,此时分配内存中存放的值是无法确定的)。
static修饰的局部变量默认值为0,并且这个变量的值具有继承性(每次调用的时候,static修饰的不会每次重新赋值,而是接着使用上一次的值)。
③可能很多同学都有疑问:为什么static的局部变量值具有继承性,为什么没有被赋值的时候,它的值为0呢?
原因是static修饰的局部变量,它的存储空间在data段(初始化)/bss段(未初始化)。这两个段在程序中编译的时候,就已经存在,程序运行的时候,直接从data/bss段取数据,所以不需要每次给它分配空间,它的值每次都存放在那里,每次需要的时候,就直接取就可以了。
其实关于在bss段分配空间,其默认为0的情况,并不确定,如果操作系统或自己写的程序没有对bss段清0,bss段的数据依然为随机值。如:在u_boot中,从汇编跳到C语言代码执行的时候,就需要设置栈和清bss段。
(2)static修饰函数或全局变量
函数名或全局变量默认是全部的,在其他文件中如果想使用它们,只需要extern关键字声明,然后再使用。
当用static修饰它们的时候,限制了它们的作用域范围,此时它们只能在它们所在的文件中使用,而在其他文件中就算用extern关键字声明,也是不可以使用的。
很多时候,我们在两个或两个以上的文件中定义了同名的函数或全局变量,在编译的时候,编译器就会报符号重复定义的错误,使用static修饰可以有效解决这个问题,但是这还是有一个问题存在“其他文件不能有效访问”。为了解决这个问题,在后来的语言发展中,提出了解决方案:如在C++中提出了命名空间(namespace),在Java中有包的概念(package)。
总结:static修饰局部变量时,改变局部变量的生命周期与局部变量值,生命周期由函数结束时释放变为整个程序结束时释放;局部变量的值由每次调用在栈区分配空间并初始化变为在程序编译的时候在静态区区域(data/bss段)分配空间且值具有继承性。
static修饰函数或全局变量时,改变函数和全局变量的作用域范围,限定该函数或局部变量只能在它们所在的文件中使用,解决了编译时多文件含有同名函数或全局变量的问题。
阅读(1255) | 评论(0) | 转发(1) |