内存分区和函数调用

内存分区和函数调用

内存分区

C++中内存分为四区:代码区、全局区、栈区和堆区。

分区存放开辟释放
代码区二进制代码程序运行前、编译后操作系统
全局区全局变量、全局常量(字符串和const修饰)程序运行前、编译后操作系统
栈区局部变量、局部常量(字符串和const修饰)程序运行后程序结束后,由编译器自动分配释放
堆区new开辟的空间程序运行后程序结束后,需要程序员delete手动释放

new举例

使用new在堆区开辟内存空间,存放数据类型的数据,返回该数据的首地址,用该数据类型的指针接收。程序结束后,使用delete调用析构函数手动释放内存空间。使用数组本质是使用数组的首地址。因此,指向数组首地址的指针可以看成是数组名,也可以当做普通指针使用。

#include<iostream>
using namespace std;
#include<string>


void test02()
{
	int *ptr = new int[5];	//在堆区开辟内存空间,存放int型数组,返回该数据(数组)的首地址。
	//1.ptr当做数组使用
	//for (int i = 0; i < 5; i++)
	//{
	//	ptr[i] = i + 100;
	//}
	//for (int i = 0; i < 5; i++)
	//{
	//	cout << ptr[i] << endl;
	//}

	//2.ptr当做指针使用
	//*ptr = 100;
	//cout << *ptr << endl;
	for (int i = 0; i < 5; i++)
	{
		*ptr = i + 100;
		ptr++;
	}
	for (int i = 0; i < 5; i++)
	{
		cout << *(ptr-1) << endl;
		ptr--;
	}

	delete []ptr;
}

int main()
{
	test02();


	system("pause");
	return 0;
}

函数调用

值传递

1)函数调用时,将实参值拷贝一份(调用拷贝构造函数),然后将拷贝值传给形参。函数调用过程不可以改变实参。
2)以值方式返回局部对象,在返回时,将返回值拷贝一份(调用拷贝构造函数),然后将拷贝的数据返回。

#include<iostream>
using namespace std;
#include<string>

//无返回型
//num01'=num01;a=num01;
void test03(int a)
{
	a = a + 10;
	cout << a << endl;
}

//返回int型
//返回时,先将返回值拷贝一份,然后将拷贝的数据返回。
int test04(int a)
{
	a = a + 10;
	cout << a << endl;
	return a;
}


int main()
{
	int num01 = 10;
	//调用test函数,过程:将实参拷贝一份,然后将拷贝的数据传递给形参。
	test03(num01);
	int num02 = test04(num01);

	system("pause");
	return 0;
}

地址传递

1)函数调用时,将实参的地址传给形参。函数的调用过程可以改变实参。

#include<iostream>
using namespace std;
#include<string>

//无返回型
void test05(int *p)
{
	*p = *p + 10;
}

//返回指针型
int* test06(int *p)
{
	*p = *p + 100;
	return p;
}


int main()
{
	int num01 = 10;
	//调用test函数,过程:将实参地址传递给形参。
	test05(&num01);
	cout << "num01的值:" << num01 << endl;

	int num02 = 10;
	int *ptr = test06(&num02);
	cout << "num02的值:" << num02 << endl;

	system("pause");
	return 0;
}

引用传递

1)函数调用时,将实参的引用传给形参。可以改变实参。
2)以引用返回局部对象,在返回时,将局部对象的引用返回。注意不要返回局部对象的引用,因为局部对象存储在栈上,函数调用结束后,编译器会自动释放栈区内存。
3)引用的本质是一个指针常量,引用一旦初始化,指向就不可以发生更改。常量引用(const修饰)使指向的值也不可以更改。

#include<iostream>
using namespace std;
#include<string>

//无返回型
void test07(int &ref)
{
	ref = ref + 10;
}

//返回引用型
int& test08(int &ref)
{
	ref = ref + 100;
	return ref;
}

//常量引用
void test09(const int &ref)
{
	//ref = ref + 10;常量引用不可改变引用的值。
	cout <<"打印的值:" << ref << endl;
}


int main()
{
	int num01 = 10;
	//调用test函数,过程:将实参引用传递给形参。
	test07(num01);
	cout << "num01的值:" << num01 << endl;

	int num02 = 10;
	int num03 = test08(num02);
	cout << "num02的值:" << num03 << endl;

	int num04 = 30;
	test09(num04);

	system("pause");
	return 0;
}

总结

在函数调用时,值传递的方式传参和返回局部对象会调用拷贝构造函数将实参拷贝一份,因此使用引用传递和地址传递的效率更高。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值