C++核心编程
本阶段主要是针对C++面向对象编程技术做详细讲解。
1:内存的分区模型
C++执行程序时,将内存大方向分为4个区域
- 代码区和全局区是在程序运行前存在的:
- 代码区:存放函数体的二进制代码,由操作系统进行管理
- 全局区:存放全局变量和静态变量以及常量
- 栈区和堆区:是程序运行后存在的
- 栈区:由编译器自动分配释放,存放函数的参数值和局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收
内存四区意义:
不同区域存放的数据,其生命周期不同,给我们更大的灵活编程
1.1程序执行前
程序编译后,生成exe可执行程序,未执行该程序前分为两个区域
代码区:
存放CPU执行的机器指令
代码区时共享的。
代码区时只读的。防止意外修改
全局区:
全局变量和静态变量存放在此。
全局区还包括了常量区(字符串常量和其他常量)。
特点:该区域的数据在程序运行后由操作系统释放。
#include<iostream>
using namespace std;
//全局区 全局变量 静态变量 常量
//全局变量 没有写在函数体内的变量都是全局变量
int g_a = 10;
int g_b = 10;
const int g_c_a = 10;
const int g_c_b = 10;
int main()
{
//局部变量 在函数体内的变量时局部变量
int a = 10;//局部变量
int b = 10;
cout << "局部变量a的地址" << (int)&a << endl;
cout << "局部变量a的地址" << (int)&b << endl;
cout << "全局变量g_a的地址" << (int)&g_a << endl;
cout << "全局变量g_b的地址" << (int)&g_b << endl;
//静态变量 在普遍变量前加static
static int s_a = 10;
static int s_b = 10;
cout << "静态变量s_a的地址" << (int)&s_a << endl;
cout << "静态变量s_a的地址" << (int)&s_b << endl;
//常量 字符串常量 const修饰的变量
cout << "字符串常量的地址为" << (int)&"hello" << endl;
//const修饰的全局变量
cout << "const修饰的全局变量g_c_a的地址" << (int)&g_c_a << endl;
cout << "const修饰的全局变量g_c_a的地址" << (int)&g_c_b << endl;
//const修饰的局部变量
const int c_a = 10;
const int c_b = 10;
cout << "const修饰的局部变量c_a的地址" << (int)&c_a << endl;
cout << "const修饰的局部变量c_a的地址" << (int)&c_b << endl;
system("pause");
return 0;
}
1.2程序运行后
栈区:
由编译器自动分配释放,存放函数的参数值,局部变量等
注意事项:不要返回局部变量的地址,栈区开辟的数据由编译器自动释放
#include<iostream>
using namespace std;
//栈区数据的注意事项----不要返回局部变量的地址
//栈区的数据由编译器管理和释放
int* func()
{
int a = 10;//局部变量 存放在栈区,栈区的数据在函数执行完成后释放
return &a;//返回了a的地址
}
int main()
{
//接收函数的返回值
int* p = func();
cout << *p << endl;//第一次打印时正确的 因为编译器做了保留
cout << *p << endl;//第二次打印时错误的 数据不在保留
system("pause");
return 0;
}
堆区
堆区由程序员分配和释放 ,如果程序员不释放,程序结束由操作系统回收。
在C++中主要利用new在堆区开辟内存。
#include<iostream>
using namespace std;
int * func1()
{
//利用new得到一个新的堆区
//*p是栈区的局部变量 将堆区的编号
//指针 本质也是局部变量 放在栈上,指针保存的数据是放在堆区。
int * p = new int(19);
return p;
}
int main()
{
//在堆区开辟数据
int * p = func1();//指针指向的地址为地址上的数
cout << *p << endl;
cout << *p << endl;
cout << *p << endl;
system("pause");
return 0;
}
总结:
堆区数据由程序员管理和释放
堆区数据利用new关键字进行开辟
1.3new操作符
C++中利用new关键字来开辟堆区;
堆区的数据是由程序员进行开辟和释放的 释放需要用delete操作符号
语法:new 数据类型
利用new开辟堆区 是返回该堆区对应数据的指针。
#include<iostream>
using namespace std;
//1、new的基本语法
int * func2()
{
int * p = new int(90);
return p;
}
void test01()
{
int * p = func2();
cout << * p << endl;
cout << *p << endl;
cout << *p << endl;
//堆区的数据操作系统不会释放 由程序员手动释放 利用关键字delete
delete p;
//cout << *p << endl;//数据已经被释放 再次访问会报错
}
//2、在堆区利用new开辟数组
int* func4()
{
int* arr = new int[10];
for (int i = 0; i < 10; i++)
{
arr[i] = i + 100;
}
return arr;
}
void test02()
{
int* arr = func4();
for (int i = 0; i < 10; i++)
{
cout << arr[i] << endl;
}
delete[] arr;//释放数据的时候要告诉编译器
}
int main()
{
test01();
test02();
system("pause");
return 0;
}