c/c++ static关键字详解

static关键字

在函数体中

static关键字作用在函数体内部的变量,也就是局部静态变量
存储位置

不同的局部变量存储在栈中

而被static修饰的局部变量存储在静态存储区中,即使函数退出,他也不会被销毁

cpp 复制代码
void test1() {
    int a, b;
    static int c;
    printf("a: %p\n", &a);
    printf("b: %p\n", &b);
    printf("c: %p\n", &c);
}

// 输出:
// a: 0x7fffd8bbe550
// b: 0x7fffd8bbe554
// c: 0x584bef710018

上面例子可以发现,a和b的地址是紧邻的,而和他们声明在一起的c的地址则没有
生命周期

普通局部变量在进入函数时创建,退出函数时销毁

静态局部变量在程序启动时分配内存,在程序结束时释放,它的生命周期贯穿整个程序
作用域

局部静态变量,名字已经很清楚了,他的作用域只能是在这个函数内部,函数外是无法访问的。但是每次调用这个函数的时候,访问的都是同一个静态变量

cpp 复制代码
void counter() {
    static int count = 0; // 静态局部变量
    count++;
    cout << "调用次数: " << count << endl;
}

int main() {
    for (int i = 0; i < 3; i++)
        counter();
    return 0;
}

// 输出
// 调用次数: 1
// 调用次数: 2
// 调用次数: 3

在模块中

c/c++中的模块一般指的是某个源文件或者一个头文件被多个源文件包含的情况,此时static关键字的核心作用是限制符号(变量或函数)只能在当前编译单元中可见,也就是说,它限制了符号的连接属性,从"外部链接"变为"内部链接"

cpp 复制代码
// file1.cpp
int a=0;
static int b=0;

void increase() {
    a++;
    b++;
    std::cout << a << " " << b << std::endl;
}

static void increase2() {
    a++;
    b++;
    std::cout << a << " " << b << std::endl;
}

// file2.cpp
extern int a;
extern void increase();
extern int b;
extern void increase2();
int main() {
    increase(); // 可以,increase函数没有被static限制
    increase2(); // 不可以
    std::cout << a << std::endl; // 可以
    std::cout << b << std::endl; // 不可以
}

注意,你只写extern int b extern void increase2()是不会报错的,这时候你只是告诉编译器我要从其他文件中引用一个变量一个函数,但是当你使用他们的时候,编译器就得去找你使用的到底是哪个变量哪个函数了,然后因为b和increase2()是内部链接的,编译器发现找不到,此时就会报错undefined未定义

在类中

static作用在类中,包括作用在类成员变量和类成员函数,称为类的静态成员,此时static关键字的核心作用是让该成员属于类本身,而不属于某个对象
修饰类成员变量

特点:

  1. 归属:static修饰的成员属于类,而不属于某个对象;
  2. 内存:所有对象共享一份静态成员的内存,而不是每个对象一份;
  3. 访问方式:建议类名::变量名,也可以对象.变量名
  4. 定义:必须在类外单独定义并初始化
cpp 复制代码
class Counter {
public:
    static int count; // 声明静态成员变量
    Counter() { count++; }
};

// 在类外定义并初始化
int Counter::count = 0;

int main() {
    Counter a, b, c;
    cout << Counter::count << endl; // 输出:3
    return 0;
}

修饰类成员函数

特点:

  1. 调用方式:建议类名::函数名()
  2. 限制:不能访问类的非静态成员变量或函数
  3. static修饰类成员函数的目的通常是用于访问静态数据或与对象无关的操作
cpp 复制代码
class Counter {
private:
    int id;
    static int count;
public:
    Counter() { count++; }

    static void showCount() {  // 静态成员函数
        cout << "当前对象数: " << count << endl;
        // cout << id; 错误:不能访问非静态成员
    }
};

int Counter::count = 0;

int main() {
    Counter a, b;
    Counter::showCount(); // 通过类名调用
    a.showCount();        // 也可以通过对象调用
    return 0;
}
相关推荐
HRBorderInsight1 小时前
马来西亚人均收入一个月多少钱,个人薪资和家庭收入要分开看
经验分享·笔记
又見山3 小时前
本地 Markdown 与数据主权:你的笔记到底属于谁
笔记·obsidian
撩得Android一次心动4 小时前
Jetpack Compose 知识点整理2【个人用】
android·笔记·学习·kotlin·compose
cao23334 小时前
关于 x1 y1 等变量名冲突的指正(校对版)
笔记
Demons_kirit5 小时前
CTFHub 信息泄露通关笔记:Git泄露 Log - 教程
笔记·git·网络安全
德思特6 小时前
2026 低空经济无人机与 eVTOL GNSS 模拟器选型指南:四大硬核标准与设备推荐
经验分享·gnss
xhyu616 小时前
【学习笔记】图像质量评估方法 (5.生成图像是否符合用户要求)
笔记·学习·计算机视觉
丰色木夕6 小时前
Ubuntu22.04下源码编译安装USD-Brep
c++·ubuntu·nvidia·usd-brep
恒锐丰科技林技术员7 小时前
EG2103 高压 MOS/IGBT 驱动芯片解析:半桥驱动的高性价比之选
经验分享·嵌入式硬件·硬件工程
2601_961146207 小时前
实验室用等离子表面处理设备处理新能源汽车塑料件的一点记录
笔记·汽车·设备