c语言和c++中的静态关键字

static的核心作用可以归结为两个维度:存储期(生命周期)链接属性(可见范围)。

C++ 完全继承了 C 中 static 的所有用法,但在此基础上,针对**类(Class)**增加了两个全新的上下文。这是两者最本质的区别。

第一板块:C 和 C++ 共有的用法(底层内存逻辑)

在这一层,static 操作的是内存布局编译链接,与你之前学习的进程地址空间(代码段、数据段)紧密相关。

1. 修饰局部变量(改变存储期)

普通局部变量:存储在栈区,函数结束即销毁。

静态局部变量 :存储在静态存储区 (属于进程地址空间中的 .data 或 .bss 段),生命周期贯穿整个程序运行期 ,但作用域仍仅限于该函数内部。

核心特性:只在第一次执行到定义时初始化,之后调用保持上次的值。

cpp 复制代码
#include <stdio.h>

void counter() {
    static int count = 0; // 只初始化一次,存储在静态区
    count++;
    printf("调用次数: %d\n", count);
}

int main() {
    counter(); // 输出 1
    counter(); // 输出 2 (保留了上一次的值)
    return 0;
}
2. 修饰全局变量或函数(改变链接属性)

在 C/C++ 项目中,默认情况下全局变量和函数具有外部链接(External Linkage) ,即可以被其他 .c / .cpp 文件通过 extern 访问。

加上 static 后,将其改为内部链接(Internal Linkage)作用域被限制在当前源文件(编译单元)内,别的文件无法看到它。

这不仅是为了安全(封装),也能有效防止多文件编译时的重名冲突

cpp 复制代码
// file: math_utils.c

// 全局静态变量:只能在本文件中使用,其他文件看不见
static int s_internal_counter = 100; 

// 静态函数:只能在本文件中调用,不会暴露给外部接口
static void helper_function() {
    printf("内部辅助函数\n");
}

// 普通函数:可以被外部文件调用
void public_function() {
    helper_function(); // 内部调用是允许的
}

第二板块:C++ 独有(类的静态成员)------ 最大的区别

这是 C 语言完全没有的领域。static 在这里不再关注"文件",而是关注"类(Class)"。

3. 静态成员变量(属于类,不属于对象)

内存归属 :无论创建多少个类对象(实例),静态成员变量只有一份内存副本 ,存放在全局静态区。它不属于某个具体的 this 对象。

初始化 :必须在类外 单独定义和初始化(除非使用 C++17 的 inline 修饰),因为它是"类级别"的资源,不能在构造函数中初始化。

cpp 复制代码
#include <iostream>
using namespace std;

class Student {
public:
    static int total_count; // 声明:统计一共创建了多少个学生

    Student() {
        total_count++; // 每构造一个对象,总数+1
    }
};

// 定义并初始化静态成员变量(必须在类外进行)
int Student::total_count = 0; 

int main() {
    cout << Student::total_count << endl; // 输出 0(通过类名直接访问)
    Student s1, s2;
    cout << Student::total_count << endl; // 输出 2
    cout << s1.total_count << endl;       // 输出 2(虽然可以通过对象访问,但本质是同一个)
    return 0;
}
4. 静态成员函数(属于类,无 this 指针)

没有 this 指针 :因此它不能访问类的普通成员变量(非静态)和普通成员函数,因为它不知道要操作哪个对象。

可访问范围 :只能访问静态成员变量 和其他静态成员函数

调用方式 :可以直接通过 类名::函数名() 调用,不需要创建对象。

cpp 复制代码
class Tool {
private:
    static int version;
    int id; // 普通成员变量
public:
    static void showVersion() {
        cout << "Version: " << version << endl; // 正确,访问静态变量
        // cout << id << endl; // 报错!无法访问非静态成员,因为没有 this
    }
};

int Tool::version = 3;

int main() {
    Tool::showVersion(); // 直接通过类名调用,无需实例化
    return 0;
}
相关推荐
bksczm1 小时前
Linux之信号量(POSIX标准)
java·开发语言
吠品1 小时前
PHP里取月份最后一天的几种方式
java·开发语言·eureka
CallmeFoureyes1 小时前
使用 C# 提取 Word 文档中的表格数据
开发语言·c#·word
gugucoding2 小时前
2. 【Java】搭建Java开发环境
java·开发语言
多加点辣也没关系2 小时前
JavaScript|第9章:对象 — 基础
开发语言·javascript·ecmascript
2601_949818092 小时前
Vector从入门到应用(C++ STL动态数组万字全解
开发语言·c++
汉克老师2 小时前
GESP2026年6月认证C++八级( 第三部分编程题(1、线网建设))精讲
c++·最小生成树·排序·kruskal·并查集·gesp8级
胖大和尚2 小时前
Linux 内核工程师、HPC工程师、C++工程师
c++·kernel·hpc
汤米粥2 小时前
Python爬虫中Xpath用法之——normalize-space()
开发语言·python