C++自学笔记小记(八)(九)(十)(黑马)

本文详细介绍了C++中的内存模型,包括全局区、代码区、栈区、堆区的特性和区别,以及变量引用的使用、函数参数传递方式(值传递、地址传递和引用传递)、函数重载的概念和注意事项。
摘要由CSDN通过智能技术生成

面向对象编程自学笔记整理

八、程序的内存模型

/*******************************1.全局区*********************************/
//总结
//C++程序运行分为全局区和代码区
//代码区特点:共享与只读
//全局区存放:全局变量,静态变量,常量
//常量区中存放:const修饰的全局常量,字符串常量

//#include<iostream>
//using namespace std;
//
全局变量
//int g_a = 10;
//int g_b = 10;
const修饰的全局变量,全局常量
//const int c_a = 10;
//const int c_b = 10;
//
//
//int main()
//{
全局区
//
//
全局变量,静态变量,常量
创建普通局部变量
//	int a = 10, b = 20;
//	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,属于静态变量
//	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;
//	//const修饰的局部变量
//	const int c_la = 10;
//	const int c_lb = 10;
//	cout << "局部常量c_la的地址为:" << (int)&c_la << endl;
//	cout << "局部常量c_lb的地址为:" << (int)&c_lb << endl;
//
//	cout << "全局常量c_a的地址为:" << (int)&c_a << endl;
//	cout << "全局常量c_b的地址为:" << (int)&c_b << endl;
//	//c_const常量 g_global全局 l_local 局部
//	system("pause");
//	return 0;
//}

/*******************************2.栈区*********************************/
//#include<iostream>
//using namespace std;
//
栈区由编译器自动释放,存放函数的参数值,局部变量
注意事项:不要返回局部变量的地址,栈区开辟的地址由编译器自动释放
//
//int* func(int b)//形参变量也会存放在栈区
//{
//	b = 100;
//	int a = 10;//局部变量,存放在栈区,栈区数据在函数执行完后会自动释放
//	return &a;//返回局部变量地址
//}
//int main()
//{
//	//接受func函数返回值
//	int * p = func(10);
//	cout << *p << endl;
//	cout << *p << endl;
//
//	system("pause");
//	return 0;
//}

/*******************************3.堆区*********************************/
//#include<iostream>
//using namespace std;
//
堆区的数据由程序员决定保存和释放
//int* func()
//{
利用关键字new,可以将数据开辟到堆区
//	//指针本质为局部变量,放于栈上,指针保存的数据放在堆区
//	int *p=new int(10);
//	return p;
//}
//
//int main()
//{
//	//在栈区开辟数据
//	int* p = func();
//	cout << *p << endl;
//	system("pause");
//	return 0;
//}
/*******************************4.new操作符*********************************/
//new在堆区开辟内存空间
//delete在堆区释放内存空间

#include<iostream>
using namespace std;

//1.new的基本语法
int* func()
{
//在堆区创建整形数据
//new返回 该数据类型指针
	int* p = new int(10);
	return p;
}

void test01()
{
	int* p = func();
	cout << *p << endl;
	//堆区的数据由程序员管理开辟,由程序员管理释放
	//如果想释放堆区的数据,利用关键字delete
	delete p;
	//cout << *p << endl;//内存已经被释放,再次访问就是非法操作,会报错
}
//2.在堆区利用new开辟数组

void teat02()
{
	//在堆区创建10整形数组
	int* arr = new int[10];//代表数组有10个元素
	for (int i = 0; i < 10; i++)
	{
		arr[i] = i + 100;
	}
	for (int i = 0; i < 10; i++)
	{
		cout << arr[i] << endl;;
	}
	//释放堆区的数组
	//释放数组时需要加[]
	delete[] arr;

}

int main()
{
	test01();
	teat02();
	system("pause");
	return 0;
}


九、变量引用

/*************************1.引用的基本语法注意事项**********************************/
//#include<iostream>
//using namespace std;
//int main()
//{
引用:给变量起别名
语法:数据类型 &别名=原名;
//	/*int a = 10;
//	int& b = a;
//	cout << "a=" << a << endl;
//	cout << "b=" << b << endl;
//	b = 1000;
//	cout << "a=" << a << endl;
//	cout << "b=" << b << endl;*/
引用的注意事项:
1.引用必须要初始化
//	//int& b;//错误,必须初始化
2.引用一旦初始化就不可更改
//	int a = 10;
//	int& b = a;
//	int c = 20;
//	b = c;//赋值操作
//	cout << "a=" << a << endl;
//	cout << "b=" << b << endl;
//	cout << "c=" << c << endl;
//	system("pause");
//	return 0;
//}

/*************************2.引用做函数参数**********************************/
//#include<iostream>
//using namespace std;
交换函数
1.值传递
//void swap01(int a,int b)
//{
//	int temp;
//	temp = a;
//	a = b;
//	b = temp;
//	/*cout << "swat01 a=" << a << endl
//		<< "sawt01 b=" << b << endl;*/
//}
//
2.地址传递
//void swap02(int *a,int *b)
//{
//	int temp;
//	temp = *a;
//	*a = *b;//解引用
//	*b = temp;
//}
//
3.引用传递
//void swap03(int& a, int& b)
//{
//	int temp;
//	temp = a;
//	a = b;
//	b = temp;
//}
//
//int main()
//{
//	int a = 10, b = 20;
//	//swap01(a, b);//值传递,形参不会修饰实参
//	//swap02(&a, &b);//地址传递,形参可以修饰形参
//	swap03(a, b);//引用传递,形参可以修饰实参   
//	cout << "a=" << a << endl
//		<< "b=" << b << endl;
//	system("pause");
//	return 0;
//}

/************************* 3.引用做函数的返回值**********************************/
//#include<iostream>
//using namespace std;
//
引用做函数的返回值
1.不要返回局部变量的引用
//int& test01()
//{
//	int a = 10;//局部变量存放在栈区,函数执行完就销毁
//	return a;
//}
2.函数的调用可以作为左值
//int& test02()
//{
//	static int a = 10;//静态变量存放于全局区,全局区的数据在程序结束后释放
//	return a;
//}
//
//int main()
//{
//	//int ref1 = test01();
//	//cout << "ref1=" << ref << endl;//结果错误,内存已经释放
//	//cout << "ref1=" << ref << endl;
//	
//	int ref2 = test02();
//	while (1)
//	{
//		cout << "ref2=" << ref2 << endl;
//		cout << "ref2=" << ref2 << endl;
//	}
//	test02()=100;//函数返回值为引用,这个函数的调用可以作为左值
//	while (1)
//	{
//		cout << "ref2=" << ref2 << endl;
//		cout << "ref2=" << ref2 << endl;
//	}
//	system("pause");
//	return 0;
//}


/************************* 4.引用的本质**********************************/
//引用的本质就是在C++内部实现一个指针常量
//const (前值后向)
//const 在前 指针指向的值不可更改 const int *p=&a;
//const 在后 指针指向的方向不可更改 int *const P=&a;
//发现是引用,转换为 int *const ref=&a;
//#include<iostream>
//using namespace std;
//
//void func(int& ref)
//{
//	ref = 100;
//	//转换为*rer=100;
//}
//int nain()
//{
//	int a = 10;
//	//自动转化为int * const ref=&a;
//	//指针指向不可改变,这也就是引用不可更改的原因
//	int& ref = a;
//	ref = 20;//ref是引用,转化为*rer=20;解引用
//
//	cout << "a=" << a << endl;
//	cout << "ref=" << ref << endl;
//
//	system("pause");
//	return 0;
//}

/************************* 5.常量的引用**********************************/

#include<iostream>
using namespace std;

//打印数据函数
void showvalue(const int &value)//加const 防止形参中的数据改变实参中的值
{
	//value = 1000;//值不可更改,报错
	cout << "value=" << value << endl;

}

int main()
{
//作用:常量引用主要是用来修饰形参,防止误操作
//使用场景:可以用const修饰形参,防止形参改变形参
	//int a = 10;
	
	//const int& ref = 10;//引用必须引用一块合法的内存空间
	//加上const后,编译器将代码修改为int temp=10;  const int &ref=temp;
	//ref = 20;//报错:const(前值后向)在前,引用的值不可更改
	
	int a = 10;
	showvalue(a);
	cout << "a=" << a << endl;//发生形参中的赋值将实参中的数据更改的情况

	system("pause");
	return 0;

}

十、函数的高级应用

/********************1.函数默认参数***********************************/
//#include<iostream>
//using namespace std;
//
函数默认参数
若用户传入数据,就用用户传入数据,若没有,就用默认值
语法:返回值类型 函数名 (形参=默认值)
//int func1(int a, int b, int c)
//{
//	return a + b + c;
//}
//int func2(int a, int b=20, int c=10)
//{
//	return a + b + c;
//}
//
注意事项
1.某个位置已经有了默认参数,从这个位置往后,从左到右都必须要有默认值 
int func2(int a=10, int b, int c )
{
	return a + b + c;
}
2.如果函数的声明有了默认参数,函数实现就不能有默认参数
声明和实现只能有一个设有默认参数
//int func3(int a=10, int b=20);//函数声明
//int func3(int a, int b)//函数实现
//{
//	return a + b;
//
//}

//int main()
//{
//	cout << func1(10, 30, 20) << endl;
//	cout << func2(10,40) << endl;
//	cout << func3(10, 40) << endl;
//	system("pause");
//	return 0;
//}

/********************2.函数占位参数***********************************/
//C++中形参列表必须要有占位参数,调用该位置时必须要填补该位置
//语法:返回值类型 函数名(数据类型){}
//#include<iostream>
//using namespace std;
//
占位参数
目前阶段的占位参数还用不到,后续阶段或用到
//void func1(int a, int)
//{
//	cout << "this is func1!" << endl;
//}
//
//void func2(int a, int =10)
//{
//	cout << "this is func2!" << endl;
//}
//int main()
//{
//	func1(10, 10);
//	func2(10);
//	system("pause");
//	return 0;
//}


/********************3.函数重载***********************************/
//作用:函数名相同,提高复用性
//函数重载的条件
/*
1.同一个作用域
2.函数名称相同
3.函数参数类型不同或者个数不同或者顺序不同
*/
//注意:函数返回值不可以作为函数重载的条件
//#include<iostream>
//using namespace std;
//
条件1.必须在同一个作用域下
条件2.函数名称相同
条件3.函数参数类型不同,或者个数不同,或者顺序不同
//
//void func()
//{
//	cout << "func的调用" << endl;
//}
//
//void func(int a)
//{
//	cout << "func(int a)的调用!" << endl;
//}
类型不同
//void func(double a)
//{
//	cout << "func(double a)的调用!" << endl;
//}
顺序不同
//void func(int a, double b)
//{
//	cout << "func(int a,double b)的调用!" << endl;
//}
//
//void func(double a, int b)
//{
//	cout << "func(double a,int b)的调用!" << endl;
//}
//
注意:函数返回值不可以作为函数重载的条件
int func(double a, int b)
{
	cout << "func(double a,int b)的调用!" << endl;
}
//
//
//int main()
//{
//	func();
//	func(10);
//	func(3.145);
//	func(3, 4.5);
//	func(3.3, 3);
//	system("pause");
//	return 0;
//
//}

/********************4.函数重载的注意事项***********************************/
#include<iostream>
using namespace std;

//函数重载的注意事项
//1.引用作为重载条件
void func(int& a)//int &a=10 不合法;
{
	cout << "func(int &a)的调用" << endl;
}
void func(const int& a)//const int &a=10;合法
{
	cout << "func(const int &a)的调用" << endl;
}
 
//2.函数重载作为函数的默认参数,出现二义性
void func2(int a,int b=10)
{
	cout << "func2(int a,int b)的调用" << endl;
}
void func2(int a)
{
	cout << "func2(int a)的调用" << endl;
}

int main()
{
	//int a = 10;//变量传入,选择上面的调用
	//func(a);
	//func(10);
	//func2(10);//当函数重载碰到默认参数,会出现二义性,产生歧义,函数重载不加默认参数报错
	system("pause");
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值