C语言
前言
上一篇博客详细介绍了volatile关键字,这篇博客介绍一下static关键字
一、static关键字
static修饰的对象是局部变量、全局变量、函数。对于变量,static将改变他们在内存中链接的位置。
1.static修饰局部变量
静态局部变量、局部变量的区别主要通过生存周期和作用域
函数每次访问的静态局部变量,该变量的值为最后一次访问修改后的值。
- 生存期延长:静态变量的生存期在程序的整个运行期间,而不仅仅是在声明它的函数调用期间。这意味着静态变量会在程序启动时分配内存,并在程序终止时释放内存。这与自动变量(局部变量)不同,后者的生存期仅限于其所在函数的执行期间。
- 保持状态:静态变量的值在函数调用之间保持不变。每次调用包含静态变量的函数时,该变量的值会保持在上一次调用结束时的状态。这对于需要在多次函数调用之间共享信息的情况非常有用,例如计数器或缓存。
我们先来看一个例子就很清楚了
#include <stdio.h>
void func()
{
int a = 1;
printf("a= %d \n",a++);
}
int main(int argc, char **argv)
{
func();
func();
func();
func();
return 0;
}
这个运行之后会输出什么,很明显是四个1
然后我们用static修饰局部变量a
#include <stdio.h>
void func()
{
static int a = 1;
printf("a= %d \n",a++);
}
int main(int argc, char **argv)
{
func();
func();
func();
func();
return 0;
}
可以看到结果,这样就很显而易见了,在实际使用中,如果一个数据你只想初始值是1另外的值是计算得到的,这样写就会方便很多。
2.static修饰全局变量
静态全局变量、全局变量的区别主要通过生存周期和作用域来区别
- 作用域限制:静态全局变量的作用域被限制在声明它的源文件(或编译单元)内部,不能在其他文件中被访问。这使得该变量对于文件内的其他函数来说是可见的,但无法在其他文件中访问。这有助于确保全局变量的私有性,防止其他文件无意或恶意地修改它。
- 数据保持性:静态全局变量在程序的整个运行期间保持其值,而不会像普通全局变量那样被销毁和重建。这使得它适用于需要保持状态的情况,例如跟踪应用程序的配置设置、日志级别等信息。
- 命名空间隔离:静态全局变量的名称在整个程序中具有唯一性,因为它们只在其源文件内部可见。这减少了全局命名冲突的风险,因为其他文件可以有相同名称的全局变量,而不会导致冲突。
我们还是直接看代码
现在有两个.c文件 1.c和mian.c 我们在1.c中定义变量A
int A = 1;
void test(void)
{
A = 11;
}
然后在main.c中打印变量A
extern int A;
void main(void)
{
printf("A: %d\r\n", A);
}
很明显这个A打印出来是11
然后我们用static修饰这个全局变量
static int A = 1;
void test(void)
{
A = 11;
}
extern int A;
void main(void)
{
printf("A: %d\r\n", A);
}
这个时候你在编译,程序就会报错
这说明A的作用域被限制在1.c中了,使用extern都无法被其他的文件使用。
3.static修饰函数
在C语言中,使用static
关键字来声明静态函数是一种常见的用法,它具有以下主要作用:
- 作用域限制:静态函数的作用域被限制在声明它的源文件(或编译单元)内部,不能在其他文件中被访问。这有助于确保函数的私有性,防止其他文件中的代码无意或恶意地调用它。
- 命名空间隔离:静态函数的名称在整个程序中具有唯一性,因为它们只在其源文件内部可见。这减少了命名冲突的风险,因为其他文件中可以有相同名称的函数,而不会导致冲突。
- 模块封装:静态函数通常用于实现文件范围的辅助功能,以便在同一文件内的多个函数之间共享代码,但不希望其他文件能够访问这些辅助函数。这有助于将相关功能封装在一个文件中,以提高代码的模块化和可维护性。
static函数(也叫内部函数)只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用。
// 文件: 1.c
#include <stdio.h>
// 静态函数,只在当前文件内可见
static void Function()
{
printf("HAHAHA");
}
void Function1()
{
printf("LALALA\n");
Function(); // 可以调用静态函数
}
// 文件: main.c
#include "1.c"
int main()
{
Function1(); // 可以调用公共函数
// Function(); // 编译错误,无法访问静态函数
return 0;
}