首页 > 编程语言 >C++中static初始化一次的真实含义

C++中static初始化一次的真实含义

时间:2024-11-30 20:44:18浏览次数:6  
标签:初始化 变量 作用域 C++ static 内存地址 赋值

1. static 变量的初始化与赋值

static 变量在 C++ 中有一个特别的性质:它们在程序的生命周期内只会被初始化一次,但之后可以继续对其进行赋值。

  • 初始化static 变量在程序的初始化阶段(即程序第一次执行时)会被初始化一次。如果是局部 static 变量,则它会在第一次执行到该变量所在的代码行时被初始化;如果是全局或静态作用域内的变量,则会在程序启动时初始化。

  • 赋值:初始化之后,static 变量的值是可以改变的。赋值操作不会改变 static 变量的内存地址,也就是说,static 变量的内存地址在整个程序运行期间是固定的。赋值只会改变该内存地址中存储的数据,而不会影响变量的地址。

示例:static 变量的初始化和赋值

#include <iostream>

void testStatic() {
    static int x = 10;  // 初始化只发生一次
    std::cout << "x = " << x << std::endl;
    x = 20;  // 赋值,但不重新初始化
    std::cout << "x after assignment = " << x << std::endl;
}

int main() {
    testStatic();  // 第一次调用,初始化并赋值为 10
    testStatic();  // 第二次调用,x 已初始化,赋值为 20
    return 0;
}

输出:

x = 10
x after assignment = 20
x = 20
x after assignment = 20

在这个例子中,x 是 static 变量:

  • 第一次调用 testStatic() 时,x 会被初始化为 10,之后赋值为 20。
  • 第二次调用 testStatic() 时,x 不会重新初始化,而是保持上次赋的值(20),并可以继续赋值。

内存地址不变:无论你如何对 x 进行赋值,x 的内存地址始终不变,它依然指向同一块内存位置。

2. 普通变量的初始化与赋值

对于普通的局部变量,每次进入其作用域时,该变量会被重新初始化,并且会在栈上分配新的内存空间。普通变量 可以多次初始化,但每次进入作用域时,都会重新为该变量分配内存(除非它是动态分配的,如使用 new)。

  • 初始化:每次进入作用域时,局部变量都会被重新初始化,并且会重新分配栈空间。
  • 赋值:可以在初始化之后对普通变量进行赋值,但赋值不等于初始化。赋值操作会改变该变量存储的值,而不会影响它的内存位置(除非你是指针类型)。

示例:普通局部变量的初始化和赋值

#include <iostream>

void testNormal() {
    int x = 10;  // 每次进入函数时都会初始化
    std::cout << "x = " << x << std::endl;
    x = 20;  // 赋值,但内存地址不变
    std::cout << "x after assignment = " << x << std::endl;
}

int main() {
    testNormal();  // 第一次调用,初始化为 10
    testNormal();  // 第二次调用,重新初始化为 10
    return 0;
}

输出:

x = 10
x after assignment = 20
x = 10
x after assignment = 20

在这个例子中,x 是普通的局部变量:

  • 每次调用 testNormal() 时x 会被重新初始化,并且会重新分配栈空间。
  • x 的值在初始化后可以被赋值为其他值,但它的内存地址在每次调用 testNormal() 时都是新的,栈空间会被重新分配。

3. 对比:static 变量与普通变量的差异

特性static 变量普通局部变量
初始化 只初始化一次,在程序启动或首次调用时初始化 每次进入作用域时初始化
赋值 之后可以多次赋值,但不改变内存地址 可以多次赋值,但内存地址随每次进入作用域不同
内存管理 只有一块内存空间,内存地址固定 每次进入作用域时会重新分配内存
生命周期 整个程序运行期间(从程序启动到结束) 仅在作用域内有效,出作用域时销毁

4. 栈空间与堆空间的对比(内存分配)

  • 栈空间(stack):局部变量(普通变量)通常存储在栈上。每次进入作用域时,栈空间会为变量分配内存,离开作用域时销毁。这是 自动内存管理

  • 堆空间(heap):使用 new 或 malloc 分配的内存则来自堆。堆上的内存通常需要显式释放(如通过 delete 或 free),否则会导致内存泄漏。

5. 结论

  • static 变量:初始化只发生一次,内存地址在整个程序的生命周期内固定,不会发生变化。之后的赋值只是改变其存储的值,而不会改变内存地址。
  • 普通局部变量:每次进入作用域时会重新分配内存,并且会重新初始化。因此,每次函数调用时,局部变量的内存空间是不同的。

总结来说,static 变量不会在每次调用时重新分配内存,它的内存地址是固定的,而普通局部变量每次进入作用域时都会重新分配内存,内存地址不同。

标签:初始化,变量,作用域,C++,static,内存地址,赋值
From: https://www.cnblogs.com/chentiao/p/18578838

相关文章

  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——15.C++11(2)
    1.可变模板参数C++11引入的可变模板参数(variadictemplates)使得模板参数的数量可以是任意多个,极大地提升了C++的模板编程能力。以下是C++11中可变模板参数的详细总结:1.基本语法在模板参数列表中,通过...(三个点)来表示可变参数。常见的使用形式如下:template<typena......
  • 智能值针初始化方式
    智能指针的初始化方式根据智能指针的类型(如 std::shared_ptr 或 std::unique_ptr)以及具体需求而有所不同。以下是详细介绍:1. 初始化 std::shared_ptrstd::shared_ptr 是一种引用计数智能指针,允许多个 shared_ptr 共享同一块内存。(1)使用 std::make_shared(推荐)std::ma......
  • 读书笔记:C++程序设计原理与实践(基础篇)之八
    “程序员的工作不仅是写代码,而是解决问题。”                                        ——SteveMcConnell总阅读时间约为 5~10分钟。前言在本系列第二篇博文中【读书笔记:C++程序设计原理与实践(基础篇)之二-CSDN博客】,我们......
  • 打卡信奥刷题(336)用C++工具信奥P2813[普及组/提高] 母舰
    母舰题目背景广东汕头聿怀初中Train#3Problem1(有没有红警既视感~)题目描述在小A的星际大战游戏中,一艘强力的母舰往往决定了一场战争的胜负。一艘母舰的攻击力是普通的MA(MobileArmor)无法比较的。对于一艘母舰而言,它是由若干个攻击系统和若干个防御系统组成的。两......
  • ACM输入输出模板(上)【Java、C++版】
    文章目录1、多行输入,每行两个整数C++Java2、多组数据,每组第一行为n,之后输入n行两个整数C++Java3、输入若干行,每行输入两个整数,遇到特定条件终止C++Java4、若干行输⼊,遇到0终止,每行第⼀个数为N,表示本行后面有N个数C++Java5、若干行输入,每行包括两个整数a和b,由空格分隔......
  • C++语言之旅【3】---引用(很重要的知识点!!!)
    本章概述引用彩蛋时刻!!!引用引用的概念:引用就是给变量取个新的别名。引用的定义格式:类型&别名=引用对象。给大家用代码展示一下引用的格式://引用的格式:inta=0;int&b=a; //b就是a的引用,就相当于给a取别名为b引用解释:引用不是新定义一个变量,只是给变量取个......
  • C/C++头文件以及避免头文件包含造成的重定义方法
    头文件是扩展名为 .h 的文件,包含了C函数声明和宏定义,被多个源文件中引用共享。有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。在程序中要使用头文件,需要使用C预处理指令 #include 来引用它。前面我们已经看过 stdio.h 头文件,它是编译器自带的头文件。......
  • 【C++算法】21.二分查找算法_山脉数组的峰顶索引
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:852.山脉数组的峰顶索引题目描述:解法暴力解法:若:arr=[0,1,2,3,2,1,0]可以定义一个指针指向第一个元素,如果它后面的元素比它大,那么他就不是峰值。当第一次遇到一个数是大于后面那个数的时候,那个数就......
  • 【C++习题】22.二分查找算法_寻找峰值
    文章目录题目链接:题目描述:解法C++算法代码:图解题目链接:162.寻找峰值题目描述:解法暴力解法:三种山峰的情况开始元素比它后面一个元素大的话直接就是山峰了(因为nums[-1]=nums[n]=-∞)普通山峰最后一个元素比前面一个元素大的话直接就是山峰了二分算......
  • [C++][CMake][Error] set_target_properties called with incorrect number of argume
    1简介这篇文章将探讨了在使用CMake构建C++项目时,调用set_target_properties函数时参数数量不正确所引发的问题。2错误案例以下为可能发生错误的案例include_directories(${CMAKE_SOURCE_DIR}/common)find_package(Threads)add_library(libusbmuxdSHAREDlibusbm......