文章目录
前言
一、静态变量和全局变量、局部变量的区别、在内存上是怎么分布的?
1.1.静态变量
1.1.1.全局/命名空间作用域中的静态变量
1.1.2.类中的静态变量
1.1.3.注意事项
1.2.全局变量
1.2.1.特点
1.2.2.声明与定义
1.2.3.注意事项
1.3.局部变量
1.3.1特点
1.3.2.注意事项
1.4.三者的区别
1.4.1. 全局变量(Global Variables)
1.4.2. 局部变量(Local Variables)
1.4.3. 静态变量(Static Variables)
1.4.4.区别总结
二、指针和引用的区别
2.1. 定义和使用
2.2. 内存占用
2.3. 初始和重新绑定
2.4. 与 null 的关系
2.5. 数组和函数参数
三、C++内存分区
3.1. 栈(Stack)
3.2. 堆(Heap)
3.3. 全局/静态存储区(Static Storage)
3.4. 常量存储区(Constant Storage)
3.5. 代码区(Text Segment)
3.6. 数据段(Data Segment)
3.7. BSS段(Block Started by Symbol)
3.8. 内存分配和回收
总结
本文首先介绍了静态变量、全局变量和局部变量的区别,包括它们在内存中的分布情况。接着,我们探讨了指针和引用的不同用法及其背后的原理。最后,我们详细解释了C++程序在运行时的内存布局,包括栈、堆和全局/静态存储区的角色和相互作用。
一、静态变量和全局变量、局部变量的区别、在内存上是怎么分布的?
在C++中,静态变量(static
变量)是一种特殊的变量存储类别,它在程序的整个运行期间只被初始化一次,并且其生命周期与程序的运行期相同。静态变量可以用于类中或全局/命名空间作用域中,它们的行为和用途各有不同。
在全局或命名空间作用域中声明的静态变量具有以下特点:
extern
关键字在其他文件中声明)。// file1.cpp
static int global_static_var = 10;
void function1() {
global_static_var++;
std::cout << "In function1: " << global_static_var << std::endl;
}
// file2.cpp
extern int global_static_var;
void function2() {
global_static_var++;
std::cout << "In function2: " << global_static_var << std::endl;
}
在类中声明的静态变量具有以下特点:
//创建类对象访问
class MyClass {
public:
static int staticVar;
void display() {
std::cout << "Static var: " << staticVar << std::endl;
}
};
// 在类外初始化静态变量
int MyClass::staticVar = 0;
int main() {
MyClass obj1, obj2;
obj1.display(); // 显示静态变量的值
obj2.display(); // 显示静态变量的值
MyClass::staticVar = 5;
obj1.display(); // 显示更新后的静态变量的值
obj2.display(); // 显示更新后的静态变量的值
return 0;
}
//使用类直接访问
#include
class MyClass {
public:
static int staticVar;
void display() {
std::cout << "Static var via instance: " << staticVar << std::endl;
}
static void displayStaticVar() {
std::cout << "Displaying static var: " << staticVar << std::endl;
}
};
int MyClass::staticVar = 0; // 静态成员初始化
int main() {
MyClass::displayStaticVar(); // 直接通过类名访问静态成员函数
MyClass obj;
obj.display(); // 通过对象访问静态成员
MyClass::staticVar = 100;
std::cout << "Static var after update: " << MyClass::staticVar << std::endl;
return 0;
}
在C++中,全局变量是在所有函数外部定义的变量,它们具有全局作用域,这意味着它们可以在整个程序的任何位置被访问(除非被局部作用域中的同名变量遮蔽)。全局变量的生命周期从定义它们的语句执行时开始,直到程序结束时结束。
extern
关键字。// global_variable.cpp
#include
// 定义并初始化全局变量
int globalVar = 10;
// 函数声明
void showGlobalVar();
int main() {
std::cout << "In main: " << globalVar << std::endl;
showGlobalVar();
return 0;
}
// 函数定义
void showGlobalVar() {
std::cout << "In showGlobalVar: " << globalVar << std::endl;
}
//使用 extern 声明全局变量
//如果你在一个文件中定义了全局变量,你可以在其他文件中使用 extern 关键字来声明它,
//以便在其他件中访问这个全局变量。
// global_variable.h
#ifndef GLOBAL_VARIABLE_H
#define GLOBAL_VARIABLE_H
extern int globalVar; // 声明全局变量
#endif
// file1.cpp
#include "global_variable.h"
#include
void modifyGlobalVar() {
globalVar = 20; // 修改全局变量
std::cout << "In modifyGlobalVar: " << globalVar << std::endl;
}
// global_variable.cpp
#include "global_variable.h"
int globalVar = 10; // 定义并初始化全局变量
int main() {
std::cout << "In main: " << globalVar << std::endl;
modifyGlobalVar();
return 0;
}
尽管全局变量在某些情况下很方便,但它们通常不推荐在大型或复杂的项目中使用,因为它们可能导致代码难以理解和维护。在可能的情况下,建议使用局部变量、参数传递或封装在类中的成员变量。
在C++中,局部变量是在函数、代码块或任何其他作用域内部声明的变量。局部变量只在其声明的作用域内可见,一旦退出该作用域,局部变量的生命周期就会结束,其占用的内存也会被释放。
++
)或递减(--
)运算符时,应注意它们是前缀形式还是后缀形式,这会影响返回值。局部变量是C++编程中的基础概念,正确理解和使用局部变量对于编写清晰、有效的代码非常重要。
extern
关键字在其他文件中声明)。注意:文件作用域中的静态变量不能使用 extern
来改变其链接性,因为它们默认具有内部链接性,并且它们的作用域被限制在定义它们的文件内。类中的静态成员变量或函数可以使用 extern
关键词将其具有外部链接性。extern
关键字主要用于具有外部链接性的全局变量或函数,以便它们可以在声明它们的文件之外的其他文件中访问。
理解这些变量的区别对于编写有效和可维护的C++程序非常重要。正确选择变量的作用域和生命周期可以帮助管理内存使用,避免作用域冲突,并确保程序的正确性。
在C++中,指针和引用是两种不同的机制,用于访问和操作变量。尽管它们在某些方面有相似之处,但它们之间存在一些关键的区别。
指针:
&
运算符获取变量的地址,并使用 *
运算符来解引用指针,访问它所指向的变量的值。int var = 10;
int* ptr = &var; // ptr 指向 var
int value = *ptr; // value 为 10,通过 ptr 访问 var 的值
引用:
int var = 10;
int& ref = var; // ref 是 var 的引用
int value = ref; // value 为 10,直接通过 ref 访问 var 的值
指针:
引用:
指针:
引用:
指针:
nullptr
(C++11及以后版本),表示它不指向任何对象。引用:
指针:
引用:
在C++中,内存分区主要分为以下几个部分:
new
和 delete
操作符分配和释放堆内存。const
修饰的变量。new
进行分配,使用 delete
进行回收。本文介绍了C++中变量的存储类别、指针与引用的区别以及程序运行时的内存布局。这些基础知识对于C++程序员来说非常重要,因为它们影响着程序的性能、内存使用和数据安全。正确理解和使用这些概念可以提高代码质量,避免常见的编程错误。