C++系统学习_01

#include<iostream>

using namespace std;


/*截止71之后转为此笔记
* struct 结构体名称 {结构体}
①结构体数组 struct student stu[5]{   
---输入信息
};
熟练写冒泡,循环交换

通讯录实操
*/


/*C++核心编程--面向对象

C++在执行的时候内存大致分为4区

代码区: 存放函数体的二进制代码,由操作系统管理  (程序运行前就有)      编译后生成exe可执行程序

全局区:存放全局变量和静态变量以及常量		(程序运行前就有)         global全局  static静态  const常量  local本地局部 
       结束后数据由操作系统释放   【全局和静态变量放得很近,常量离得也不远,但局部变量地址离得远】 只要局部修饰的,局部常量仍在局部区,离全局区远

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

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

*/

int* func() 
{
	int a = 10;//局部变量,存放在栈区,栈区的数据在函数执行完后自动释放
	return &a; //返回局部变量的地址 ,局部变量地址返回后就被释放
}

void testfunc() {
	int * p = func();  //接受返回值   

	cout << *p << endl;//因为局部被释放,此处非法操作!!
	cout << *p << endl;//第一次防止误操作仍10,第二次就不是了
}

int * func2() {
	//利用new关键字 ,可以将数据开辟到堆区  
	//指针本质也是局部变量,放在栈上,指针保存的数据是放在堆区   
	
	//在堆区创建整型数据
	//用new开辟空间会返回和数据类型一样的指针
	int* p = new int(10);
	return p;
}

void testfunc2() {
	int* p = func2();  //接受返回值,堆区数据,由程序员管理,程序员手动释放才释放,如果想释放delete

	cout << *p << endl;
	cout << *p << endl;
	cout << *p << endl;
	cout << *p << endl;

	delete p;  //内存访问已经被释放,再次访问就是非法操作,会报错

	cout << *p << endl;
	
}

int * func3() {//在堆区用new开辟数组
	
	//创建10整型数据的数组,在堆区
	int *arr = new int[10];	//10代表数组有10个元素

	for (int i = 0; i < 10; i++) {
		arr[i] = i + 100;   //赋值100~109
	}

	for (int i = 0; i < 10; i++) {
		cout << arr[i] << endl;
	}
	//释放数组堆区内存
	//释放数组的时候,要加[]才可以
	delete[] arr;
	return 0;
}

/*2.引用的基本使用
作用: 给变量起别名
语法:数据类型 &别名 = 原名

//引用注意事项:
*引用必须初始化
*初始化后不可以改变

*/

void quote(){
	int a = 10;
	int &b = a;   

	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

	int c = 20;
	b = c;//等号是赋值操作,而不是更改引用   ,a、b、c均为20

	cout << "a = " << a << endl;// 20
	cout << "b = " << b << endl;// 20
	cout << "c = " << c << endl;// 20
	
}
/*引用做函数参数
作用: 函数传参时,可以利用英语的技术让形参修饰实参
优点:可以简化指针修改实参

*/

void swap1(int a,int b) {//值传递
	int temp = a;
	a = b;
	b = temp;

	cout << "swap1_a = " << a << endl;//形参交换
	cout << "swap1_b = " << b << endl;
}

void testswap1() {
	int a = 10;
	int b = 20;
	swap1(a,b);
	cout << "a = " << a << endl;//值传递实参不交换
	cout << "b = " << b << endl;
}

void swap2(int *a,int *b) {//地址传递    --指针去接地址
	int temp = *a;   
	*a = *b;
	*b = temp;

	cout << "swap2_a = " << a << endl;//形参交换
	cout << "swap2_b = " << b << endl;
}


void testswap2() {
	int a = 10;
	int b = 20;
	swap2(&a, &b);//注意
	cout << "a = " << a << endl;//实参交换
	cout << "b = " << b << endl;
}

void swap3(int &a ,int &b) {//引用传递   引用给变量取别名
	int temp = a;
	a = b;
	b = temp;
}

void testswap3() {
	int a = 10;
	int b = 20;
	swap3(a, b);//取别名,也就是交换实参中的数据
	cout << "a = " << a << endl;//实参交换
	cout << "b = " << b << endl;
}

//引用做函数的返回值
//1.不要返回局部变量的引用!!
int& test1() {//返回a的引用    test1() == a的别名
	int a = 10;//局部变量存放在四区中的 栈区
	return a;
}
void test_test() {
	int& ref = test1();
	cout << ref << endl;//第一次结果正确,是因为编译器做了保留
	cout << ref << endl;//第二次结果错误,因为a的内存已经释放

}

//2.函数的引用可以作为左值
int& test2() {
	static int a = 10;//静态变量,存放在全局区,全局区上的数据在程序结束后系统释放
	return a;
}

void test_test2() {

	int& ref2 = test2();//&ref2 为a的别名
	cout << "ref2 :" << ref2 << endl;//10
	cout << "ref2 :" << ref2 << endl;

	//--->如果函数的返回值是引用,这个函数调用可以作为左值
	test2() = 1000; //test2()返回a,等效 a = 1000   

	cout << "ref2 :" << ref2 << endl;//1000
	cout << "ref2 :" << ref2 << endl;

}

/*2.5引用的本质
本质:引用的本质在C++内部实现是一个指针常量


*/

//发现是引用,转换为 int * const ref = &a;
void funcquote(int &ref) {
	ref = 100;//ref是引用,转换为*ref = 100
}

void testfuncquote() {
	int a = 10;

	//自动转换为 int * const ref = &a; 指针常量是指针指向不可改,也说明为什么引用不可更改       ref存a的地址

	int ref = a;
	ref = 20;  //内部发现ref是引用,自动帮我们转换为 *ref = 20;

	cout << "a :" << a << endl;
	cout << "ref :" << ref << endl;

	funcquote(a);
	return ;
}


/*2.5const*/

//常量引用
//const用来修饰形参 , 防止误操作



void _const() { 
	const int a = 10;
	//a = 20;  报错
	//int &ref = 10;   // 报错非常量引用初始值必须为左值, 没有合法的内存空间  
	 //加入const 就可以了,编译器优化代码,int temp = 10;const int &ref = temp;
		const int &ref = 10;  //引用必须引一块合法的内存空间!
	//ref = 20; 报错   //加入const之后变为只读,不可以修改

}

//打印数据函数  --防止忘记只是用来打印函数的,不修改,加const
void showV(const int& val) {

	//val = 1000;
	cout << "val :" << val << endl;

}

void test_const() {

	_const();
	//函数中常利用常量引用防止误操作修改实参
	int a = 10;
	showV(a);
}

/*3.函数提高
	3.1函数默认参数
		*1.注意从某个位置有默认值,那么从这个位置往后,从左到右都必须有默认值
		*2.如果函数有声明默认函数,函数实现就不能有默认参数
*/

//3.1函数默认参数
int func_han(int a,int b = 20,int c = 30)  //默认值
{
	return a + b + c;
}

//声明和实现只能有一个有默认参数!,  声明有,实现就不要加参数  ,  实现有,声明就不要加参数
// int func_han(int a, int b = 20, int c = 30);//没报错 ,但编译不过-->重复定义

int func_han(int a, int b, int c);

void test_func_han() {
	//自己传入数据,可以更改默认值   ,没有就用默认值
	//语法 : 返回值类型 函数名 (形参 = 默认值){}
	cout << func_han(10,30) << endl;   
}


//函数的占位参数
/*
返回值类型 函数名 (数据类型){}

目前阶段的占位参数,我们还用不到,后面的课程会用到



占未参数,还可以有默认参数
int funcz(int a,int = 10) {}
*/

int funcz(int a, int) { 
	cout << "this is z" << endl; 
	return 0;
}
void testfuncz() {
	funcz(10, 10);//占位参数必须填补
}

/*函数重载   可以让函数名相同,提高复用性

函数的返回值不可以作为函数重载的条件(编译器编译时对相同函数名产生歧义,返回值或函数内容不同函数名相同编译不通过)
*/

void Function_overload() {//函数_重载
	cout << "Function_overload()的调用" << endl;
}

void Function_overload(int a) {//函数_重载
	cout << "Function_overload(int a)的调用" << endl;
}

void Function_overload(double a) {//函数_重载
	cout << "Function_overload(double a)的调用" << endl;
}

void Function_overload(int a,double b) {//函数_重载
	cout << "Function_overload(int a,double b)的调用" << endl;
}

void Function_overload(double a,int b) {//函数_重载
	cout << "Function_overload(double a,int b)的调用" << endl;
}

void test_Function_overload() {
	Function_overload();
	Function_overload(10);
	Function_overload(3.14);
	Function_overload(3.14,10);
	Function_overload(10, 3.14);

}

/*函数重载注意事项  
* 1.引用作为重载条件
* 2.函数重载碰到函数默认参数


*/
//int 与 const int 属于类型不同
void overload(int &a) {//int &a = 10 不合法   10放在常量区
	cout << "overload(int &a)的调用" << endl;  
}

void overload(const int &a) {//const int &a = 10 合法,创建一个临时数据指向临时空间
	cout << "overload(const int &a)的调用" << endl;    
}

void testoverload() {
	int a = 10;//a是变量可读可写,会调用可读可写状态的
	overload(a);//overload(int &a)的调用

	//10放在常量区,int &a语法不通过,const int &a = 10 合法
	overload(10);//overload(const int &a)的调用

}

//函数重载碰到默认参数

void __overload(int a, int b = 10) {//函数_重载
	cout << "overload(dint a, int b = 10)的调用" << endl;
}

void __overload(int a) {//函数_重载
	cout << "overload(double a,int b)的调用" << endl;
}

void test__overload(int a) {
	//__overload(10);//出现二义性(歧义)   b默认不赋值也可以  ,要尽量避免这种情况出现!
	__overload(10,20);//这个就只能是overload(dint a, int b = 10)的调用,且b = 20
}

int main() {

	test_Function_overload();

	return 0;
}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值