作用域和生命周期

变量的作用域

变量的作用域指变量能在代码什么地方可以被访问到。

变量类型 作用域
全局变量 所有程序中的代码都能访问
静态全局变量 在同一个源文件中可以访问,不同源文件不可访问,也不能用extern来导入
局部变量 只能在函数内部访问
静态局部变量 只能函数内部访问
寄存器变量 只能在函数内部访问

注:如果全局变量在一个源文件中定义,在另一个源文件中访问,需要用extern关键字导入。多线程访问全局变量注意安全问题。

变量的生命周期

变量的生命周期是指变量在程序运行期间的有效时间

变量类型 生命周期
全局变量 整个程序运行期间有效
静态全局变量 整个程序运行期间有效
局部变量 函数范围内或代码块范围内有效
静态局部变量 整个程序运行期间有效
寄存器变量 函数范围内或代码块范围内有效

static和extern

static修饰全局变量

  • 表示这个全局变量只能在当前文件使用,不能在其他文件使用
  • 在不同文件可以声明同名变量
  • 修饰函数表示这是一个内部函数

static修饰局部变量

  • 延长局部变量声明周期,从程序启动到程序结束,但是没有修改变量的作用域
  • 定义变量的代码在整个程序运行期间就只执行一次

extern修饰全局变量

  • 表示这个全局变量可以在其他文件使用
  • 在不同文件不能声明同名变量
  • 修饰函数表示这是一个外部函数

extern 不能修饰局部变量

注:全局变量、静态全局变量、静态局部变量的声明周期相同,都是直到程序结束才被释放


实例:

分析下列程序中每个变量的存储位置,作用域,与生命周期

int a = 0;
char *p1;
static int x = 10;

void func(void)
{
 int b;
 char s[] = "123";
 char *p2;
 char *p3 = "hello,world";
 static int c = 0;
 register int i = 0;
 p1 = (char *)malloc(128);
 p2 = (char *)malloc(256);
 free(p1);
 free(p2);
}

int main(void)
{
 func();
 printf("hello,world\n");
 return 0;
}

解答:

int a = 0;			//全局变量,初始化
char *p1;			//全局变量,
static int x = 10;	//全局变量,初始化

void func(void)
{
    int b;				//局部变量
    char s[] = "123";	//s为局部变量,"123"为常量,初始化
    char *p2;			//局部变量
    char *p3 = "hello,world";	//p3为局部变量,"hello,world"为常量,初始化
    static int c = 0;	//局部静态变量,初始化
    register int i = 0;	//寄存器变量,初始化
    p1 = (char *)malloc(128);	//p1指向堆上的内存,直到free
    p2 = (char *)malloc(256);	//p2指向堆上的内存,直到free
    free(p1);
    free(p2);
}
变量或常量 存储空间 作用域 生命周期
a 静态区(data.) 整个工程,extern int a; 整个程序结束
p1 静态区(bbs.),指向的内存在堆上 整个工程,extern char *p1; 整个程序结束,指向的内存需要free释放。
x 静态区(data.) 当前文件 整个程序结束
b main函数 main函数结束
s main函数 main函数结束
p2 栈,指向的内存在堆上 main函数 main函数结束,指向的内存需要free释放
p3 main函数 main函数结束
c(参考demo/static) 静态区(data.) main函数 整个程序结束
i 可能是寄存器或栈 main函数 main函数结束
“hello,world”,”123” 静态区(data.) 整个程序结束

参考: