C++核心编程——内存分区、引用、函数提高和函数重载

这篇具有很好参考价值的文章主要介绍了C++核心编程——内存分区、引用、函数提高和函数重载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本专栏记录C++学习过程包括C++基础以及数据结构和算法,其中第一部分计划时间一个月,主要跟着黑马视频教程,学习路线如下,不定时更新,欢迎关注
当前章节处于:
---------第1阶段-C++基础入门
---------第2阶段实战-通讯录管理系统,
====>第3阶段-C++核心编程
---------第4阶段实战-基于多态的企业职工系统
---------第5阶段-C++提高编程
---------第6阶段实战-基于STL泛化编程的演讲比赛
---------第7阶段-C++实战项目机房预约管理系统

一、 内存分区

C++程序在执行时,内存大致方向分为4个区域,不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程。代码区和全局区是在程序运行前,栈区和堆区是在代码运行后

  • 代码区:存放函数体的二进制码,有操作系统进行管理
  • 全局区:存放全局变量和静态变量以及常量
  • 栈区:由编译器自动分配释放,存放函数的函数值,局部变量等。
  • 堆区:由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

1.1 代码区

存放CPU执行的机器指令

  • 代码区是共享的,只需要在内存中有一份代码即可
  • 代码区是只读的,防止程序意外地修改了它的指令

1.2 全局区

全局变量和静态变量存放在此。
全局区还包括了常量区,字符串常量和其他常量也存放在这里。
该区域的数据在程序结束后由操作系统释放。

#include <iostream>
using namespace std;
// 全局变量 ----- 全局区
int g_a = 0;
int g_b = 0;
// 全局常量 ----- 全局区
const int c_g_a = 0;
const int c_g_b = 0;
int main() {
	// 以下为全局区
	// 全局变量
	cout << "全局变量a的地址为" << (int)&g_a << endl;
	cout << "全局变量b的地址为" << (int)&g_b << endl;
	// 全局常量
	cout << "全局常量a的地址为" << (int)&c_g_a << endl;
	cout << "全局常量b的地址为" << (int)&c_g_b << endl;
	// 静态变量
	static int s_a = 0; // static修饰的是静态变量
	static int s_b = 0;
	cout << "静态变量a的地址为" << (int)&s_a << endl;
	cout << "静态变量b的地址为" << (int)&s_b << endl;
	// 字符串常量
	cout << "字符串常量a的地址为" << (int)&"Hallo world" << endl;


	// 以下为非全局区
	// 局部变量
	int l_a = 0;
	int l_b = 0;
	cout << "局部变量a的地址为" << (int)&l_a << endl;
	cout << "局部变量b的地址为" << (int)&l_b << endl;
	// 局部常量
	// const修饰的常量
	const int c_l_a = 0;
	const int c_l_b = 0;
	cout << "局部常量a的地址为" << (int)&l_a << endl;
	cout << "局部常量b的地址为" << (int)&l_b << endl;

	system("pause");
	return 0;

}
全局变量a的地址为1109844336
全局变量b的地址为1109844340
全局常量a的地址为1109830576
全局常量b的地址为1109830580
静态变量a的地址为1109844344
静态变量b的地址为1109844348
字符串常量a的地址为1109831072
局部变量a的地址为1807742644
局部变量b的地址为1807742676
局部常量a的地址为1807742644
局部常量b的地址为1807742676
请按任意键继续. . .

可以看到全局变量,全局常量,静态变量,字符串常量是存储在全局区,其他量存储在非全局区。

1.3 栈区

  • 由编译器自动分配释放,存放函数的参数值,局部变量等。
  • 不要返回局部变量的地址,栈区开辟的数据由编译器自动释放

1.4 堆区

程序员分配释放,若程序员不释放,程序结束由操作系统回收
在C++中主要利用new在堆区开辟内存。

#include <iostream>
using namespace std;

int* func() {
	int* p = new int(10);  // new关键字在堆区域开辟地址
	return p;
}
int main() {
	
	cout << *func() << endl;
	cout << *func() << endl;
	cout << *func() << endl;
	system("pause");
	return 0;

}
10
10
10
请按任意键继续. . .

new操作符
利用new操作符开辟数据
堆区开辟的数据,有程序员手动开辟,手动释放,释放使用delete
利用new创建的数据,会返回该数据对应的类型的指针

#include <iostream>
using namespace std;

int* func() {
	int* p = new int(10);  // new关键字在堆区域开辟地址
	return p;
}
int main() {
	
	cout << *func() << endl;
	int* p = func();
	cout << *p << endl;
	// 删除操作
	delete p;
	// cout << *p << endl; 会报错,原因是p已经从堆区域删除
	system("pause");
	return 0;

}

new在堆区开辟一个数组

#include <iostream>
using namespace std;
int* test() {
	int *arr = new int[10]; // new创建数组
	for (int i = 0; i < 10; i++) {
		arr[i] = i; // 赋值 
	}
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << endl;
	}
	return arr;
}

int main() {
	int *arr = test();
	delete[] arr; // 删除数组时要加上[]表示删除的是一个数组
	system("pause");
	return 0;

}
0
1
2
3
4
5
6
7
8
9
请按任意键继续. . .

二. 引用

2.1 引用的基本使用

作用是给变量起别名,语法: 数据类型 &别名=原名

#include <iostream>
using namespace std;


int main() {
	int a = 0;
	// 引用
	int& b = a;
	cout << "a=" << a<<endl;
	cout << "b=" << b<<endl;
	int* p = &a;
	cout << "p的值为:" << *p << endl;
	b = 10; // 同样也会修改a的值
	cout << "p的值为:" << *p << endl;
	cout << "a的值为:" << a << endl;

	cout << "a的地址为:" << (int)&a << endl;
	cout << "b的地址为:" << (int)&b << endl;
	system("pause");
	return 0;

}
a=0
b=0
p的值为:0
p的值为:10
a的值为:10
a的地址为:-289408796
b的地址为:-289408796
请按任意键继续. . .

注意事项

  • 引用必须初始化
  • 引用在创建之后就不可改变了
int &a; // 错误 未初始化!


int a = 0;
int c = 0;
// 引用
int& b = a;
int& b = c; // 报错,创建之后就不可以更改

2.2 引用做函数参数

函数传参时,可以利用引用的技术让形参修饰实参,简化指针修饰实参

#include <iostream>
using namespace std;
void swap(int &a,int&b) {
	int temp = a;
	a = b;
	b = temp;
}

int main() {
	int a = 10;
	int b = 20;
	cout << "交换前a=" << a << endl;
	cout << "交换前b=" << b << endl;
	swap(a, b);
	cout << "交换后a=" << a << endl;
	cout << "交换后b=" << b << endl;
	system("pause");
	return 0;

}
交换前a=10
交换前b=20
交换后a=20
交换后b=10
请按任意键继续. . .

引用传递和地址传递效果一样,都可以对实参进行修改。

2.3 引用做函数返回值

#include <iostream>
using namespace std;
// 不要返回局部变量的引用
//int &test() {
//	int a = 10;
//	cout <<"a的地址:"<< (int)& a << endl;
//	return a;
//}

int &test() {
	static int a = 10; // 静态变量  在全局区
	cout <<"a的地址:"<< (int)& a << endl;
	return a;
}
// 引用的格式
// int & a = b;
int main() {
	int& ref = test();

	cout << "ref的地址" << (int) & ref << endl;
	cout << "ref的地址为:" << ref << endl;
	system("pause");
	return 0;

}
a的地址:1526331140
ref的地址1526331140
ref的地址为:-858993460
请按任意键继续. . .

函数的调用可以作为左值

#include <iostream>
using namespace std;
int& test() {
	static int a = 10;// 静态变量
	return a;
}

int main() {
	int& b = test();
	cout << "b的值为:" << b<<endl;
	test() = 1000;  // 函数调用作为左值
	cout << "b的值为:" << b<<endl;
	system("pause");
	return 0;

}
b的值为:10
b的值为:1000
请按任意键继续. . .

2.4 引用的本质

引用的本质是在C++内部实现一个指针常量,由编译器内部完成
指针常量是指针的指向不可改变,但指针指向的值可以改变

#include <iostream>
using namespace std;
void test(int& x) {
	cout << x << endl;
}

int main() {
	int a = 0;
	int &b = a;  // 相当于指针常量 int const *b  = &a;  指向对象不能变,指向对象的值能变
	b = 10; // 相当于*b =10  解引用
	cout << "a的值为:" << a << endl;
	cout << "b的值为:" << b << endl;
	system("pause");
	return 0;

}
a的值为:10
b的值为:10
请按任意键继续. . .

2.5 常量引用

主要用来修饰形参,防止误操作,使用const修饰形参,防止形参修改实参

#include <iostream>
using namespace std;
void printValue(const int& a) {
	//a = 100; const修饰后不可再函数内部进行更改,防止误操作
	cout << a << endl;
}

int main() {
	int a = 10;
	printValue(a);
	system("pause");
	return 0;

}
10
请按任意键继续. . .

在写函数内部具体代码时,应该先判断是否需要使用const修饰,防止后续代码有误操作。

三. 函数提高

3.1 函数的默认参数

默认参数可以不传值,也可以重新传值进行覆盖。
注意事项:

  • 如果某个位置有默认参数,那么从这个默认参数后都应该有默认参数
  • 如果函数申明有默认参数,那么函数实现就不能有默认参数,两者只能有其一,防止重定义
#include <iostream>
using namespace std;
// 设置函数默认参数
int func(int a, int b = 20, int c = 30) {
	return a + b + c;
}
// 注意事项
// 1. 如果某个位置有默认参数,那么从这个默认参数后都应该有默认参数
// int a, int b = 20, int c; 错误

// 2.如果函数申明有默认参数,那么函数实现就不能有默认参数,两者只能有其一,防止重定义
//int func2(int a = 10, int b = 10);
//int func2(int a = 20, int b = 30) {
//	return a + b;
//}


int main() {
	cout << func(10,30) << endl;
	system("pause");
	return 0;

}
70
请按任意键继续. . .

3.2 占位参数

用于占位,调用函数时必须填补该位置,也可以设置默认参数,意义不大,但后续会用到。
语法: 返回值类型 函数名 (数据类型) {}

#include <iostream>
using namespace std;
void func(int a, int) {
	cout << a << endl;
}

int main() {
	func(1, 2);
	system("pause");
	return 0;

}
1
请按任意键继续. . .

四. 函数重载

作用:函数名可以相同,提高复用性
需要满足如下条件:

  1. 同一个作用域
  2. 函数名称相同
  3. 函数参数类型不同或者 个数不同 或者顺序不同
    函数的返回值不可作为函数重载的条件
#include <iostream>
using namespace std;

void func() {
	cout << "hallo world" << endl;
}
void func(int a) {
	cout << "hallo world" << endl;
}
int main() {
	func();
	system("pause");
	return 0;

}

抓住重载条件即可,函数参数类型不同或者 个数不同 或者顺序不同
引用作为函数重载条件

#include <iostream>
using namespace std;
void test1(int& a) {  // int&a =10 不合法
	cout << "调用的test1 int& a!" << endl;
}
void test1(const int& a) {// const int&a =10 不合法
	cout << "调用的test1! const int& a" << endl;
}


int main() {
	int a = 10;
	test1(a);
	test1(10);
	system("pause");
	return 0;

}
调用的test1 int& a!
调用的test1! const int& a
请按任意键继续. . .

函数重载遇到默认参数情况文章来源地址https://www.toymoban.com/news/detail-816093.html

#include <iostream>
using namespace std;

void test1(int a,int b=10) {
	cout << "调用int a,int b=10" << endl;
}
void test1(int a) {
	cout << "调用int a" << endl;
}
int main() {
	// test1(10); // 报错
	test1(10,20); // 不报错
	system("pause");
	return 0;

}
调用int a,int b=10
请按任意键继续. . .

到了这里,关于C++核心编程——内存分区、引用、函数提高和函数重载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 函数重载和引用【C++】

    函数重载: 重载函数是函数的一种特殊情况。 为方便使用,C++允许在 同一作用域 中声明几个功能类似的 同名 函数,但是这些同名函数的形式参数(指1.参数的个数 2.类型 3.顺序)必须 至少有一个 不同 根据这些同名函数的参数表的不同, 达成传入参数类型不同,调用的函

    2024年04月08日
    浏览(54)
  • 『C++成长记』C++入门—— 函数重载&引用

     🔥 博客主页: 小王又困了 📚 系列专栏: C++ 🌟 人之为学,不日近则日退  ❤️ 感谢大家点赞👍收藏⭐评论✍️ 目录 一、函数重载 📒1.1函数重载的概念 📒1.2函数重载的种类 📒1.3 C++支持函数重载的原理 二、引用 📒2.1引用的概念 📒2.2引用的特性 📒2.3引用的使用场

    2024年02月08日
    浏览(43)
  • C++:命名空间,缺省参数,函数重载,引用,内联函数

    个人主页 : 个人主页 个人专栏 : 《数据结构》 《C语言》《C++》 本篇博客作为C++知识总结,我们来认识命名空间,缺省参数,函数重载,引用,内联函数。 那么在介绍命名空间时,我们先用C++的方式打印\\\"hello world\\\"。 其中,using namespace std; 就是一种命名空间的使用。 在

    2024年02月11日
    浏览(45)
  • 【C++修炼之路】C++入门(中)—— 函数重载和引用

    👑作者主页:@安 度 因 🏠学习社区:StackFrame 📖专栏链接:C++修炼之路

    2024年02月02日
    浏览(36)
  • 【C++那些事儿】函数重载与C++中的“指针“——引用

    君兮_的个人主页 即使走的再远,也勿忘启程时的初心 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,我之前看过一套书叫做《明朝那些事儿》,把本来枯燥的历史讲的生动有趣。而C++作为一门接近底层的语言,无疑是抽象且难度颇深的。我希望能努力把抽象繁多的知识讲的生

    2024年02月08日
    浏览(47)
  • 【C++入门 三】学习C++缺省参数 | 函数重载 | 引用

    缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。 ①全缺省参数 ②半缺省参数 注意: 1. 半缺省参数必须从右往左依次来给出,不能间隔着给 2. 缺省参数不能在函数声明和定义中

    2024年02月06日
    浏览(42)
  • C++之入门之缺省参数&&函数重载&&引用

    重新拿起曾经尚未填的C++的坑,从现在我会继续更新C++的相关内容,希望各位能够支持 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参 (1)全缺省参数 (2)半缺省参数 (1)半

    2023年04月15日
    浏览(41)
  • 【C++起飞之路】初级——缺省参数、函数重载、引用

    缺省参数是 声明 或 定义 函数时为 函数的参数指定一个缺省值 。 在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。 缺省参数使用主要规则:调用时你只能从最后一个参数开始进行省略,换句话说,如果你要省略一个参数,你必须省略它后

    2024年02月04日
    浏览(44)
  • C++心决之命名空间、重载函数和引用

    目录 1. C++(C++98) 2. 命名空间 2.1 命名空间定义 2.2 命名空间使用 3. C++输入输出 4. 缺省参数 4.1 缺省参数概念 4.2 缺省参数分类 5. 函数重载 5.1 函数重载概念 5.2 C++支持函数重载的原理--名字修饰(name Mangling) 6. 引用 6.1 引用概念 6.2 引用特性 6.3 常引用 6.4 使用场景 6.5 传值、

    2024年04月17日
    浏览(36)
  • 【C++心愿便利店】No.2---函数重载、引用

    👧个人主页:@小沈YO. 😚小编介绍:欢迎来到我的乱七八糟小星球🌝 📋专栏:C++ 心愿便利店 🔑本章内容:函数重载、引用 记得 评论📝 +点赞👍 +收藏😽 +关注💞哦~ 提示:以下是本篇文章正文内容,下面案例可供参考 自然语言中,一个词可以有多重含义,人们可以通过

    2024年02月11日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包