【C++初学】C++核心编程(一):内存管理和引用

前言

在C++的世界里,面向对象编程(OOP)是核心中的核心。它不仅是一种编程范式,更是一种思考问题的方式。本文将带你从C++的内存分区模型出发,深入探讨引用、函数、类和对象、继承、多态以及文件操作等核心概念。通过丰富的代码示例和详细的讲解,帮助你快速掌握C++面向对象编程的精髓。

1. C++内存分区模型

C++程序在运行时,内存被划分为四个主要区域:代码区、全局区、栈区和堆区。每个区域都有其独特的用途和生命周期。

1.1 程序运行前:代码区与全局区

代码区:存放函数体的二进制代码,由操作系统管理。代码区是共享且只读的,防止程序意外修改指令。

全局区:存放全局变量、静态变量和常量。全局区的数据在程序结束后由操作系统释放。

示例代码:

cpp 复制代码
// 全局变量
int g_a = 10;
int g_b = 10;
// 全局常量
const int c_g_a = 10;
const int c_g_b = 10;

int main() {
    // 局部变量
    int a = 10;
    int b = 10;
    // 打印地址
    cout << "局部变量a地址为: " << (int)&a << endl;
    cout << "局部变量b地址为: " << (int)&b << endl;
    cout << "全局变量g_a地址为: " << (int)&g_a << endl;
    cout << "全局变量g_b地址为: " << (int)&g_b << endl;
    // 静态变量
    static int s_a = 10;
    static int s_b = 10;
    cout << "静态变量s_a地址为: " << (int)&s_a << endl;
    cout << "静态变量s_b地址为: " << (int)&s_b << endl;
    cout << "字符串常量地址为: " << (int)&"hello world" << endl;
    cout << "字符串常量地址为: " << (int)&"hello world1" << endl;
    cout << "全局常量c_g_a地址为: " << (int)&c_g_a << endl;
    cout << "全局常量c_g_b地址为: " << (int)&c_g_b << endl;
    system("pause");
    return 0;
}

1.2 程序运行后:栈区与堆区

栈区:由编译器自动分配和释放,存放函数的参数值和局部变量。注意,不要返回局部变量的地址。

堆区:由程序员手动分配和释放,若不释放,程序结束时由操作系统回收。

示例代码:

cpp 复制代码
int *func() {
    int a = 10;
    return &a; // 错误:返回局部变量的地址
}

int main() {
    int *p = func();
    cout << *p << endl; // 未定义行为
    cout << *p << endl;
    system("pause");
    return 0;
}

堆区示例:

cpp 复制代码
int* func() {
    int* a = new int(10);
    return a;
}

int main() {
    int *p = func();
    cout << *p << endl;
    delete p; // 释放堆区数据
    system("pause");
    return 0;
}
cpp 复制代码
int main()
{
	int* arr = new int[10];
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		arr[i] = i + 100;

	}
	for (i = 0; i < 10; i++)
	{
		cout << arr[i] << endl;
	}
	delete[] arr;
	system("pause");
	return 0;
}

2. 引用

引用是C++中一个非常重要的概念,它可以为变量起一个别名,简化代码并提高效率。

2.1 引用的基本使用

引用的语法是:数据类型 &别名 = 原名。

示例代码:

cpp 复制代码
int main() {
    int a = 10;
    int &b = a; // 引用b是a的别名
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    b = 100; // 修改b,a也会改变
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    system("pause");
    return 0;
}

2.2 引用注意事项

引用必须初始化。

引用初始化后不能改变。

示例代码:

cpp 复制代码
int main() {
    int a = 10;
    int b = 20;
    // int &c; // 错误:引用必须初始化
    int &c = a; // 初始化后不能更改
    c = b; // 赋值操作,不是更改引用
    cout << "a = " << a << endl;
    cout << "b = " << b << endl;
    cout << "c = " << c << endl;
    system("pause");
    return 0;
}

2.3 引用做函数参数

引用可以作为函数参数,让形参直接修改实参的值,避免指针的复杂性。

示例代码:

cpp 复制代码
void mySwap03(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

int main() {
    int a = 10;
    int b = 20;
    mySwap03(a, b);
    cout << "a:" << a << " b:" << b << endl;
    system("pause");
    return 0;
}

2.4 引用做函数返回值

引用可以作为函数的返回值,但要注意不要返回局部变量的引用。

示例代码:

cpp 复制代码
int& test02() {
    static int a = 20; // 静态变量
    return a;
}

int main() {
    int& ref2 = test02();
    cout << "ref2 = " << ref2 << endl;
    test02() = 1000; // 可以通过引用修改静态变量
    cout << "ref2 = " << ref2 << endl;
    system("pause");
    return 0;
}

2.5 引用的本质

引用在C++内部实现是一个指针常量。编译器会自动处理所有的指针操作。

示例代码:

cpp 复制代码
void func(int& ref) {
    ref = 100; // 内部转换为 *ref = 100
}

int main() {
    int a = 10;
    int& ref = a; // 自动转换为 int* const ref = &a
    ref = 20; // 内部转换为 *ref = 20
    cout << "a:" << a << endl;
    cout << "ref:" << ref << endl;
    func(a);
    system("pause");
    return 0;
}

2.6 常量引用

常量引用可以防止误操作修改实参。

示例代码:

cpp 复制代码
void showValue(const int& v) {
    cout << v << endl;
}

int main() {
    const int& ref = 10; // 编译器优化:int temp = 10; const int& ref = temp;
    cout << ref << endl;
    system("pause");
    return 0;
}
相关推荐
编程侦探2 小时前
【设计模式】适配器模式:让不兼容的接口和谐共处
开发语言·c++·设计模式·适配器模式
2401_845417452 小时前
C++ string类
java·开发语言·c++
Y.O.U..2 小时前
力扣HOT100——560.和为k的子数组
数据结构·c++·算法·leetcode
wuqingshun3141592 小时前
经典算法 判断一个图中是否有环
java·开发语言·数据结构·c++·算法·蓝桥杯·深度优先
编程见习者3 小时前
OpenCV的详细介绍与安装(一)
c++·人工智能·opencv·计算机视觉
邪恶的贝利亚3 小时前
C++ 基础深入剖析:编译、内存与面向对象编程要点解析
开发语言·c++
ChoSeitaku3 小时前
NO.93十六届蓝桥杯备战|图论基础-拓扑排序|有向无环图|AOV网|摄像头|最大食物链计数|杂物(C++)
c++·蓝桥杯·图论
Dream it possible!3 小时前
CCF CSP 第36次(2024.12)(1_移动_C++)
c++·ccf csp·csp
HackerKevn4 小时前
【项目】构建高性能多线程内存池:简化版 tcmalloc 实现指南
c++·高并发内存池·tcmalloc·池化技术
珊瑚里的鱼4 小时前
【双指针】专题:LeetCode 202题解——快乐数
开发语言·c++·笔记·算法·leetcode·职场和发展