c进阶篇(三)——static用法详解

前言:
  static是c的关键词,具有静态的含义,可以用于修饰变量和函数。

1 修饰变量

  static修饰对变量会产生三种作用效果。

  • 影响变量作用域和生存期;
  • 变量数据保持;
  • 变量未初始化时初始值为0;

1.1 影响变量作用域和生存期

1.1.1 影响变量作用域

  c语言中变量可以分为局部变量和全局变量,全局变量被 static 修饰时为全局静态变量。全局静态变量只可被变量所在文件中的函数访问,对外影藏,其他文件函数无法访问。不影响局部静态变量的作用域。

  main.c文件

1
2
3
4
int main(void)
{
printf("%d", Data); //Error: Data变量不存在
}

  Test.c文件

1
static int Data = 0;              //全局静态变量

1.1.2 影响变量生存期

  局部变量被 static 修饰时为局部静态变量,局部静态变量的生存期为从变量定义到程序运行结束。根本原因为静态变量在RAM的.data段或.bss段,而局部变量存储在栈中,函数运行结束后栈空间被释放。

1
2
3
4
5
void Fun(void)
{
static int a = 0; //函数运行结束后静态局部变量不会释放
int b = 0; //函数运行结束后局部变量会被释放
}

1.2 变量数据保持

  由于全局静态变量和静态局部变量的生存期都是从变量定义处到程序运行结束,函数运行结束并不会导致局部今天变量被释放,因此静态局部变量具有数据保持作用。

1
2
3
4
5
6
void Fun(void)
{
static int a = 0;

a += 1; //在上一次调用时值的基础上累加
}

1.3 变量未初始化时初始值为0

  初始值为0或未初始化的全局变量和静态变量存放在.bss段,换句话说存储在该段的变量初始值为0。而不同局部变量存储在动态内存栈中,若未初始化则变量初始值未知。

1
2
3
4
5
6
void Fun(void)
{
static int a; //未初始化的局部静态变量

printf("%d", a); //输出值为0
}

2 修饰函数

  普通函数定义后可以被之后定义(书写上有先后顺序)的函数直接调用,若要在其他文件中调用该函数或要在之前定义的函数中调用该函数,需要在调用的文件中增加函数声明(一般函数声明放在头文件中)。static修饰的函数称为内部函数或静态函数,静态函数只能被同文件内的其他函数调用,对其他文件是“隐藏”的。

  Test.h

1
2
3
#include "stdio.h"

extern void Fun1(void); //声明是无效的,因为是静态函数

  Test.c

1
2
3
4
5
6
#include "Test.h"

static void Fun(void) //定义静态函数
{
printf("Fun\n");
}

  main.c

1
2
3
4
5
6
7
#include "stdio.h"
#include "Test.h"

int main(void)
{
Fun(); //Error: 静态函数外部无法访问
}