C/CPP : static 关键字 及 变量函数的不同
本文由zaccur整理编辑,如需转载请注明出处。
综述
static关键字是C, C++中都存在的关键字。从字面理解是“静态的“的意思,与此相对应的,应该是“动态的“。
static的作用主要有以下3个:
局部数据:扩展生存期(C/CPP);全局数据/函数:限制作用域(C/CPP);类成员数据/函数:数据唯一性(ONLY CPP);局部数据:扩展生存期( C/CPP)
此作用主要是针对局部变量来说。
举例:
static是按照程序的生命周期来分配释放变量的,如果在main前设置断点,然后查看static变量,已经被初始化,也就是说static在执行main函数前已经被初始化。也就是在程序初始化时被分配。
引申:在程序中,常用内存类型主要有堆、栈和静态存储区。
要理解static局部变量就必须首先理解这三种内存类型。
主要区别:
1) 堆是由低地址向高地址扩展,栈是由高地址向低地址扩展。
2) 堆是不连续的空间,栈是连续的空间。
3) 在申请空间后,栈的分配要比堆的快。对于堆,先遍历存放空闲存储地址的链表、修改链表、再进行分配;对于栈,只要剩下的可用空间足够,就可分配到,如果不够,那么就会报告栈溢出。
4) 栈的生命期最短,到函数调用结束时;静态存储区的生命期最长,到程序结束时;
堆中的生命期是到被我们手动释放时(如果整个过程中都不手动释放,那就到程序结束时)。
引申:存储说明符auto,register,extern,static的存储期
全局数据/函数:限制作用域( C/CPP)
此作用主要针对全局变量来说。
补充:在C语言中,static对于全局变量/函数的作用:隐藏。
当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性。
举例说明。我们要同时编译两个源文件,一个是xxx.c,另一个是main.c。
所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。
如果加了static,就会对其它源文件隐藏。
此例中,g_var是全局变量,msg是函数,并且都没有加static前缀,因此对于另外的源文件main.c是可见的。
例如在g_var和msg的定义前加上static,main.c就看不到它们了。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量(局部变量),static还可以扩充其生命周期,同时初始化的时候直接默认赋值0(全局变量默认)。
类成员数据/函数:数据唯一性( ONLY CPP)
此作用是C++对static关键字的重用。主要针对类里静态成员数据/成员函数。
在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指成员变量/函数在此类中的唯一性。
表示static成员变量和函数属于一个类而不是属于此类的任何特定对象的变量和函数.
这是与普通成员函数的最大区别, 比如在对某一个类的对象进行计数时,计数生成多少个类的实例,都可以用到静态数据成员。 (针对静态数据成员而言, 成员函数不管是否是static,在内存中只有一个副本,普通成员函数调用时,需要传入this指针,static成员函数调用时,没有this指针。)
static数据成员的初始化:
(1) 初始化在类体外进行,而前面不加static,以免与一般静态变量或对象相混淆。
(2) 初始化时不加该成员的访问权限控制符private,public等。
(3) 初始化时使用作用域运算符来标明它所属类,因此,静态数据成员是类的成员,而不是对象的成员。
(4) 静态数据成员是静态存储的,它是静态生存期,必须对它进行初始化。
static成员函数:
静态成员函数和静态数据成员一样,它们都属于类的静态成员,都不是任何对象的成员。
因此,对静态成员的引用不需要用对象名。
静态成员函数仅能访问静态的数据成员,不能访问非静态的数据成员,也不能访问非静态的成员函数,这是由于静态的成员函数没有this指针。
参考:
c/c++ static 用法总结(三版本合一)来自 </mznewfacer/article/details/6898005>
C/C++中extern关键字详解 来自 </yc_sunniwell/archive//07/14/1777431.html>