day06 内存 函数进阶 类(1)

目录

内存分区模型

引用

函数

类和对象

封装


内存分区模型

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

局部普通变量:写在函数语句里面(局部区)

全局变量:写在程序的最开头(全局区)

静态变量:在普通变量前面加static(全局区)

字符串常量:(全局区)

const修饰变量:全局变量(全局区)、局部变量(局部区)

栈区:不要返回局部变量的地址,栈区的数据由编译器管理开辟和释放

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

#include<iostream>
using namespace std;

int *func() {
    //利用new,可以将数据保存到堆区,new返回的是该数据类型的指针
	int* p = new int(10);
    //指针,本质上也是局部变量,放在栈上,指针指向的数据放在堆区
	return p;
}

void test_02() {
	int* arr = new int[10];//代表数组有10个元素
	for (int i = 10;i < 10;i++) {
		arr[i] = i + 100;//给每个元素赋值
	}
    for (int i = 0;i < 10;i++) {
		cout << arr[i] << endl;
	}
    delete []arr;//释放数组 需要加[]
}

int main() {
	
	int* p = func();
	cout << *p << endl;//如果想释放,利用delete
    delete p;
    //cout << *p << endl;//内存已经被释放,再次访问就是非法操作,会报错

    

	system("pause");
	return 0;
}

引用

本质:在C++内部实现是一个指针常量,引用一旦初始化后,就不可以发生改变

#include<iostream>
using namespace std;

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

int main() {
	int a = 10;
	//自动转换为 int* const ref = &a;指针常量是指针指向不可改,因此引用也不可更改
	int& ref = a;
	ref = 20;//ref为引用,转换为 *ref = 20;解引用用来更改指向数据
	cout << "a = " << a << endl;
	cout << "ref = " << ref << endl;

	system("pause");
	return 0;
}

作用:给变量起别名,别名和原名指向同一个地址,更改后不改变地址,改变指向数据

语法:数据类型 &别名 = 原名;

int a = 10;
int& b = a;

注意事项:1.引用必须初始化(error:int &b;)

                2.初始化后不许改变(error:int a = 10,c=20;int &b = a;int &b = c;)

                3.引用必须引用合法的内存空间(error:int &b = 10;)

但是可以进行赋值操作

int a = 10;
int& b = a;
int c = 20;
b = c;//赋值操作,不是更改地址

引用做函数参数:可以简化指针修改实参,通过引用参数产生效果和地址传递是一致的

#include<iostream>
using namespace std;

void mySwap03(int& a, int& b) {
	int temp = a;
	a = b;
	b = temp;
}

int main() {
	
	int a = 10;
	int b = 20;
	mySwap03(a, b);//引用传递,形参会修饰实参
	cout << "swap03 a = " << a << endl;
	cout << "swap03 b = " << b << endl;

	system("pause");
	return 0;
}

引用做函数返回值

注:1、不要返回局部变量的引用,局部变量存放在栈区

        2、函数的调用可以作为左值

#include<iostream>
using namespace std;

int& test02() {
	//静态变量,存放在全局区,全局区上的数据在程序结束后由系统释放
	static int a = 10;
	return a;
}

int main() {
	
	int& ref2 = test02();
	cout << "ref2 = " << ref2 << endl;
	cout << "ref2 = " << ref2 << endl;
	test02() = 1000;//如果函数的返回值是引用,这个函数调用可以作为左值
	//ref2 = test02 = a;
	cout << "ref2 = " << ref2 << endl;
	cout << "ref2 = " << ref2 << endl;

	system("pause");
	return 0;
}

 常量引用:在函数形参列表中,可以加const修饰形参,防止形参改变实参

#include<iostream>
using namespace std;

void showValue(const int& val) {//打印数据函数
	//val = 1000;//error:表达式必须是可修改的左值
	cout << "val = " << val << endl;
}

int main() {
	//加上const之后,编译器将代码修改 int temp = 10;const int& ref = temp;
	const int& ref = 10;
	//加入const之后变为只读,不可以修改
	//ref = 20;//error:表达式必须是可修改的左值
	int a = 100;
	showValue(a);
	cout << a << endl;

	system("pause");
	return 0;
}

函数

函数默认参数

注:1、如果某个位置已经有了默认参数,那么从这个位置后,从左到右都必须有默认值

int func2(int a, int b = 10, int c) {//error:默认实参不在形参列表的结尾
	return a + b + c;
}

        2、如果函数声明有默认参数,函数实现就不能有默认参数,声明和实现只能有一个默认参数

int func2(int a = 10, int b = 10);//声明

int func2(int a = 10, int b = 10) {//实现
	return a + b;
}

函数占位参数:C++中函数的形参列表里可以有占位参数,用来做占位,调用函数必须填补该位置

#include<iostream>
using namespace std;

void func(int a,int) {
	cout << "this is func" << endl;
}
//占位参数,可以有默认参数
void func1(int a, int = 10) {
	cout << "this is func" << endl;
}

int main() {
	func(10,10);
	func1(10);
}

函数重载:函数名可以相同,提高复用性

满足条件:1、同一个作用域下

                2、函数名称相同

                3、函数参数类型不同,或者个数不同,或者顺序不同

#include<iostream>
using namespace std;

void func() {
	cout << "func 的调用" << endl;
}
void func(int a) {
	cout << "func(int a) 的调用" << endl;
}
void func(int a,double b) {
	cout << "func(int a,double b) 的调用" << endl;
}
void func(double b,int a) {
	cout << "func(double b,int a) 的调用" << endl;
}

int main() {
	
	func();
	func(10);//类型不同
	func(1,1.234);//个数不同
	func(1.234, 1);//顺序不同
}

:1、函数的返回值不可以作为函数重载的条件(error:无法重载仅按返回值类型区分的函数)

        2、引用作为函数重载条件

        3、函数重载碰到默认参数

#include<iostream>
using namespace std;

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;
}

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(2);//当函数重载碰到默认参数,会出现二义性,应避免这种情况
}

类和对象

封装

封装的意义

  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制
#include<iostream>
using namespace std;

const double PI = 3.14;

//设计一个圆类,求圆的周长
//求圆的周长:2*PI*半径

class Circle {//圆类,class代表一个类
    //类中的属性和成员,统一称为 成员
public:
	//属性 成员属性 成员变量
	int m_r;
    int m_d;
	//行为 成员函数 成员方法
    void getd(int d) {
        m_d = d;
    }
	double calculateRC() {
		return 2 * PI * m_r;
	}
    double calculateDZ() {
        return PI * m_d;
    }
};

int main() {
	//通过圆类 创建具体的圆(对象),实例化(通过一个类来创建一个对象的过程)
	Circle c1;
	//给圆类中的对象进行赋值
	c1.m_r = 10;
    c2.calculateRZ();
    Circle c2;
    c2.getd(20);
    c2.calculateDZ();

	cout << "圆的周长为:" << c1.calculateZC() << endl;
}

访问权限:1、公共权限 public        成员 类内可以访问,类外也可以访问

                2、保护权限 protected        成员 类内可以访问,类外不可以访问,可以继承

                3、私有权限 private        成员 类内可以访问,类外不可以访问,不可以继承

struct默认权限为公共,类外不可直接访问

class默认权限为私有,类外可以直接访问

私有:1、将所有成员属性设置为私有,可以自己控制读写权限

        2、对于读写权限,可以检测数据有效性

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

class Person {
public:
	//设置姓名 
	void setName(string name) {
		m_Name = name;
	}
	string getName() {
		return m_Name;
	}
	void setAge(int age) {//设置年龄,范围是0~255
		if (age < 0 || age>255) {
			m_Age = 0;
			cout << "输入有误" << endl;
			return;
		}
		m_Age = age;
	}
	int getAge() {
		//m_Age = 18;//年龄初始化
		return m_Age;
	}
	void setLover(string lover) {
		m_Lover = lover;
	}
private:
	string m_Name;//可读可写
	int m_Age;//只读
	string m_Lover;//只写
};

int main() {
	Person p;
	p.setName("张三");
	cout << p.getName() << endl;
	p.setAge(100);
	cout << p.getAge() << endl;
	p.setLover("petter");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值