关注微信公众号“熬夜不缺转氨酶”,获取更多嵌入式文章。
static 关键字不仅可以用来修饰变量,还可以用来修饰函数。
在使用 static 关键字修饰变量时,我们称此变量为静态变量。
1、STATIC用途
static可用来修饰局部变量,全局变量,函数
问题一:static全局变量与普通的全局变量有什么区别 ?
全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。
全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。
这两者的区别在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。
在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用。
问题二:static局部变量和普通局部变量有什么区别 ?
把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。
static局部变量只被初始化一次,下一次依据上一次结果值;
问题三:static函数与普通函数有什么区别?
static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件.
static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝。
2、STATIC作用总结
作用1:隐藏与隔离的作用
- 对全局变量使用static修饰, → 只在本文件中使用
- 对函数使用static修饰 → 只能在本文件引用
作用2:保持变量内容的持久性
- 希望函数中局部变量的值在函数调用结束之后不会消失,而仍然保留其原值。即它所占用的存储单元不释放,在下一次调用该函数时,其局部变量的值仍然存在,也就是上一次函数调用结束时的值。这时候,我们就应该将该局部变量用关键字 static 声明为“静态局部变量”
**特性:**当将局部变量声明为静态局部变量的时候,也就改变了局部变量的存储位置,即从原来的栈中存放改为静态存储区存放。
这让它看起来很像全局变量,其实静态局部变量与全局变量的主要区别就在于可见性,静态局部变量只在其被声明的代码块中是可见的。
作用3:默认初始化为0
其实全局变量也具备这一属性,因为全局变量也存储在静态数据区。
作用4:
- 在修饰变量的时候,static修饰的静态局部变量只执行一次,而且延长了局部变量的生命周期,直到程序运行结束以后才释放。
3、如何调用其他文件的static函数
第一种
• include 目标static函数的.c文件
//a.c
#include <stdio.h>
//#include "b.h"
#include "b.c"
int main(void)
{
test_func();
return 0;
}
// b.c
#include <stdio.h>
static void test_func(void)
{
printf("test static");
}
第二种
• 通过函数包住static函数,另一文件调这个函数
//a.c
#include <stdio.h>
int main(void)
{
func();
return 0;
}
// b.c
#include <stdio.h>
static void test_func(void)
{
printf("test static");
}
void func(void)
{
test_func();
}
第三种
• 通过static的地址调用
//a.c
#include <stdio.h>
#include "b.h"
int main(void)
{
func();
func_t();
return 0;
}
// b.c
#include <stdio.h>
#include "b.h"
static void test_func(void)
{
printf("test static");
}
void func(void)
{
func_t = test_func;
}
//b.h
void (*func_t)(void);
void func(void);
4、C++中使用static
- 具有在C中的作用
- 具有在类中的作用
- 修饰静态数据成员和静态成员方法
静态成员:
- (1)静态数据成员可以实现多个对象之间的数据共享,它是类的所有对象的共享成员,它在内存中只占一份空间,如果改变它的值,则各对象中这个数据成员的值都被改变。
- (2)静态数据成员是在程序开始运行时被分配空间,到程序结束之后才释放,只要类中指定了静态数据成员,即使不定义对象,也会为静态数据成员分配空间。
- (3)静态数据成员可以被初始化,但是只能在类体外进行初始化,若为对静态数据成员赋初值,则编译器会自动为其初始化为0
- (4)静态数据成员既可以通过对象名引用,也可以通过类名引用。
静态成员函数:
- (1)静态成员函数和静态数据成员一样,他们都属于类的静态成员,而不是对象成员。
- (2)非静态成员函数有this指针,而静态成员函数没有this指针。
- (3)静态成员函数主要用来方位静态数据成员而不能访问非静态成员。