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(); // 第一次调用,初始化并赋值为 10testStatic(); // 第二次调用,x 已初始化,赋值为 20return 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(); // 第一次调用,初始化为 10testNormal(); // 第二次调用,重新初始化为 10return 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
变量不会在每次调用时重新分配内存,它的内存地址是固定的,而普通局部变量每次进入作用域时都会重新分配内存,内存地址不同。