C++学习笔记(九)

在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第九篇博客。

本篇博客介绍了C++的内存区域和引用。

本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。

目录

内存区域

内存分区

代码区

全局区

栈区

堆区

引用

引用的基本使用

引用的注意事项

引用作为函数参数

引用作为函数返回值

引用的本质

常量引用


内存区域

内存分区

C++程序执行时,内存大方向划分为4个区域:

代码区:存放函数体的二进制代码,由操作系统进行管理。

全局区:存放全局变量和静态变量,以及常量。

栈区:由编译器自动分配释放,存放函数的参数,局部变量等。

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

不同区域存放不同数据,生命周期不同,编程时更灵活。

在程序编译后,生成后缀名为exe的可执行的程序,未执行该程序前分为两个区域:代码区和全局区。

代码区

代码区存放CPU执行的机器指令。

代码区是共享的,对于频繁被执行的程序,只需要一份空间就足够。

代码区是只读的,防止程序意外修改指令。

全局区

全局区存放全局变量静态变量,还包含常量区,存放字符串常量const修饰的全局常量

该区域的数据在程序结束后由操作系统释放。

普通变量前加static就属于静态变量。

全局变量定义在函数外。

#include<iostream>
using namespace std;
int a = 5;
int b = 10;
const int c = 10;
const int d = 10;
int main(void)
{
	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;
	cout << &d << endl;

	int a = 5;
	int b = 10;
	const int c = 10;
	const int d = 10;
	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;
	cout << &d << endl;

	static int e = 10;
	static int f = 15;
	cout << &e << endl;
	cout << &f << endl;
	return 0;
}

程序的一个输出示例是:

00007FF7F5DED000
00007FF7F5DED004
00007FF7F5DEABB0
00007FF7F5DEABB4
000000605072FA14
000000605072FA34
000000605072FA54
000000605072FA74
00007FF7F5DED008
00007FF7F5DED00C

可见全局变量a,b,c,d和静态变量e,f的地址差异较小,位于全局区。而main函数内的变量a,b,const修饰的局部变量c,d的地址差异较小,位于栈区。

不同区域的地址值差异较大。

栈区

栈区由编译器分配释放,存放函数的参数局部变量。栈区数据由编译器自动释放。
 

堆区

堆区由程序员分配释放,如果程序员不释放,程序结束时由操作系统回收。

C++中,new在堆区开辟内存。new的用法是:

new 数据类型(初始值)

后面数据类型是要开辟的数据类型,初始值可以为空,这时为默认值(如整数为0)。

new如果开辟成功,会返回此数据类型的一个指针,指向这块空间。

new开辟的数据需要释放,用关键字delete,格式是:

delete 动态开辟的指针

#include<iostream>
using namespace std;
int* func(void);
int main(void)
{
	int* p;
	p = func();
	cout << *p << endl;
	delete p;
	return 0;
}

int* func(void)
{
	int* p = new int(10);
	cout << *p << endl;
	return p;
}

程序的输出是:

10
10

程序的func函数中用new动态开辟了一块空间,存放一个整数,并初始化为10。随后输出值,并将指针返回main函数,main函数再度输出后释放空间。

#include<iostream>
using namespace std;
int* func(void);
int main(void)
{
	int* p;
	p = func();
	int i;
	for (i = 0; i < 10; i += 1) {
		cout << *(p + i) << endl;
	}
	delete[] p;
	return 0;
}

int* func(void)
{
	int* p = new int[10];
	int i;
	for (i = 0; i < 10; i += 1) {
		*(p + i) = i;
	}
	return p;
}

这段代码中,func函数创建了一块空间,存放有10个整数元素的数组,并依次存放0-9,随后将首元素地址返回main函数,main函数遍历输出后释放空间。

程序依次输出0-9。

引用

引用的基本使用

引用的作用是给变量起别名。引用的语法是:

数据类型 &别名 = 原名;

#include<iostream>
using namespace std;
int main(void)
{
	int a = 10;
	int& b = a;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	b = 15;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	return 0;
}

程序的输出是:

a = 10
b = 10
a = 15
b = 15

为变量a起了别名b,随后通过b修改了a的值。

引用的注意事项

引用必须初始化,初始化后不可指向其他变量。

#include<iostream>
using namespace std;
int main(void)
{
	int a = 10;
	int& b = a;
	int c = 15;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	b = c;
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	return 0;
}

程序的输出是:

a = 10
b = 10
a = 15
b = 15

b = c是将c的值赋给b。

引用作为函数参数

函数传参时,可以利用引用让形参修饰实参,这样也可以修改实参。

#include<iostream>
using namespace std;
void swap(int& m, int& n);
int main(void)
{
	int a = 10;
	int b = 15;
	swap(a, b);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	return 0;
}

void swap(int& m, int& n)
{
	int temp;
	temp = m;
	m = n;
	n = temp;
}

程序的输出是:

a = 15
b = 10

swap函数用引用接收了a和b的值,并进行交换。swap函数结束后main函数的a,b值也发生了交换。

引用作为函数返回值

引用也可以是函数返回值。不要返回局部变量的引用。

在一个函数中使用静态变量时,静态变量没有随着函数的结束而消失,而是保持着值,下一次调用该函数时,静态变量的值依然不变。静态变量在程序结束后被回收。

#include<iostream>
using namespace std;
int& test() {
	static int num = 5;
	return num;
}
int main(void)
{
	int &p = test();
	cout << p << endl;

	test() = 10;
	cout << p << endl;
	return 0;
}

程序的输出是:

5

10

引用的本质

引用的本质是一个指针常量。

常量引用

常量引用可以修饰形参,防止误操作。

#include<iostream>
using namespace std;
void show(const int& num);
int main(void)
{
	int n = 15;
	show(n);
	return 0;
}

void show(const int& num)
{
	cout << num << endl;
}

程序的输出是15

用const修饰num,防止被修改。如果在show函数中试图修改num的值,会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值