变量的生命周期、作用域与静态变量

变量的生命周期、作用域与静态变量

一、变量的生命周期和作用域

  • 生命周期:变量在程序中存在的时间(从创建到销毁的过程)。
  • 作用域:变量可被访问的范围(在哪里能用,在哪里不能用)。

变量的生命周期和作用域,由其定义位置决定,主要分为以下几类:

1. 全局变量

  • 定义形式:在函数体外声明,如 int g = 40;
  • 生命周期:程序级别(从程序启动到程序结束,全程存在)。
  • 作用域:从定义语句开始,到整个程序结束(所有函数内部均可访问)。
#include<stdio.h>

int g = 40; // 全局变量

void bar(int a) {
    printf("bar:g = %d\n", g); // 可访问全局变量g
}

int main(void) {
    printf("main:g = %d\n", g); // 可访问全局变量g
    return 0;
}

2. 局部变量

  • 定义形式:在函数体内声明,如 int x = 30;(包括函数形参,如 void bar(int a) 中的 a)。在主函数内声明,如int y = 10;
  • 生命周期:函数级别(从函数被调用时创建,函数执行结束后销毁)。
  • 作用域:从定义语句开始,到所在函数的 } 结束(仅在当前函数内可访问)。
#include<stdio.h>


void bar(int a){ // 函数的形参a也是局部变量
    int x = 30; // 局部变量
    printf("bar:x = %d\n",x); // 可访问局部变量x
}
int main(void){

    int y = 10; // 局部变量
    printf("mian:y = %d\n",y); // 可访问局部变量y
    
    return 0;
}

3. 块级变量(定义在代码块内部)

  • 定义形式:在 {} 包裹的代码块内声明,如 ifforwhile 的循环体或单独的 {} 中。
  • 生命周期:块级别(从代码块执行时创建,代码块执行结束后销毁)。
  • 作用域:从定义语句开始,到所在代码块的 } 结束(仅在当前代码块内可访问)。
int main(void) {
    
    {
        int z = 10; // 块级变量
        printf("z = %d\n", z); // 可访问块级变量z
    }
    // printf("z = %d\n", z); // 错误:超出作用域,无法访问z
    return 0;
}

4.全局变量、局部变量、块级变量总结

//变量的生命周期和作用域
//根据定义的位置不同,生命周期和作用域也不同
#include<stdio.h>

// 全局变量,定义在函数之外的变量
// 生命周期:程序级别
// 作用域:从定义语句开始,其下(编译器的执行顺序是从上往下)所有函数可用
int g = 40;//全局变量

void bar(int a){//函数的形参a也是局部变量
    int x = 30;//局部变量
    printf("bar:x = %d\n",x);//可访问局部变量x
    
    printf("bar:g = %d\n",g);//可访问全局变量g
    
    // printf("z = %d\n", z);//错误:超出作用域,无法访问z
}
int main(void){


    // 块级变量,定义在一对{}里的变量
    // 生命周期:{}级别
    // 作用域:从定义语句开始到}之间
    // 可以是if,for,while的大括号里面
    {
        int z = 10;//块级变量
        printf("z = %d\n",z);//可访问块级变量z
    }
    
    // printf("z = %d\n", z);//错误:超出作用域,无法访问z

    // 局部变量,定义在函数内部的变量
    // 生命周期:函数级别
    // 作用域:从定义语句开始到函数}之间
    int y = 10;//局部变量
    printf("mian:y = %d\n",y);//可访问局部变量y
    
    printf("mian:g = %d\n",g);//可访问全局变量g
    
    return 0;
}

二、静态变量(用 static 修饰的变量)

静态变量的核心特点是生命周期为程序级别(与全局变量一致),但作用域根据类型不同而有差异。

1. 静态局部变量(static 修饰的局部变量)

  • 定义形式:在函数内部用 static 声明,如 static int s = 10;
  • 生命周期:程序级别(从程序启动到程序结束,全程存在,不会随函数调用结束而销毁)。
  • 作用域:与普通局部变量一致(仅在所在函数内可访问)。

特殊点

  • 初始化语句仅在程序启动时执行一次(无论函数被调用多少次,都不会重复初始化)。
  • 变量值会被 “保留”:函数调用结束后,值不会丢失,下次调用时可继续使用。
#include<stdio.h>

void bar(void) {
    static int s = 10; // 静态局部变量,仅初始化一次
    printf("s = %d\n", s); 
    s = 20; // 修改值,下次调用时保留此值
}

int main(void) {
    bar(); // 输出 s = 10(首次调用,使用初始值)
    bar(); // 输出 s = 20(第二次调用,使用上次修改后的值)
    return 0;
}

2. 静态全局变量(static 修饰的全局变量)

  • 定义形式:在函数体外用 static 声明,如 static int a = 10;
  • 生命周期:程序级别(与普通全局变量一致)。
  • 作用域:仅在当前文件内可访问(普通全局变量可被其他文件访问)。

3. 静态函数(static 修饰的函数)

  • 作用:限制函数的作用域为当前文件(普通函数可被其他文件调用)。
  • 定义形式static void bar(void) { ... }

三、静态全局变量与普通全局变量的区别(多文件场景)

当程序包含多个 .c 文件时,两者的差异主要体现在跨文件访问上:

类型跨文件访问性
普通全局变量其他文件通过 extern 声明后可访问
静态全局变量仅当前文件可访问,其他文件无法访问

示例(多文件场景)

文件 1:test1.c

// static int a = 10; // 静态全局变量:test2.c 无法访问
int a = 10; // 普通全局变量:test2.c 可访问
int b = 20;

// static void bar(void) { ... } // 静态函数:test2.c 无法调用
void bar(void) { ... } // 普通函数:test2.c 可调用

文件 2:test2.c

#include<stdio.h>

// 外部声明(访问其他文件的全局变量和函数)
extern int a;
extern int b;
extern void bar(void);

int main(void) {
    printf("main:a = %d\n", a); // 可访问test1.c中的a
    bar(); // 可调用test1.c中的bar()
    return 0;
}

总结

  • 变量的生命周期和作用域由定义位置决定(全局、局部、块级)。
  • 静态变量的核心是生命周期为程序级别,但作用域受 static 限制(局部静态变量作用域为函数内,全局静态变量作用域为当前文件)。
  • 多文件场景中,static 可限制全局变量和函数的作用域,避免跨文件的命名冲突。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

基于python的毕设

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值