5.11
1、内存分区
内存分区,分为四个区,代码区、全局区、堆区、栈区
代码区存储写入的代码
全局区存储全局变量,静态变量,常量,由操作系统进行释放
栈区,存放局部变量,存放函数形参,程序执行完毕自动释放,这个地方一个注意点,栈区存放函数形参,函数执行完形参区域自动释放,所以不能返回形参的地址
堆区,程序员开辟和释放的一块内存,操作系统也可以进行释放,new操作符进行开辟,返回地址
栈区的注意点
#includeusing namespace std; int* test() { int a = 10; return &a; } int main() { int* p = test(); cout << *p << endl;//第一次正确因为编译器有所保留 cout << "hehe" << endl;//随便加入一行代码 cout << *p << endl;//此处解引用p的数据为一乱码 system("pause"); return 0; }
2、new操作符
new操作符可在堆区开辟一块所需的内存,进行数据的传递与读取,delete可进行人为地释放
#includeusing namespace std; int* test() { int arry[10]; for (int i = 0; i < 5; i++) { arry[i] = i; } for (int i = 0; i < 5; i++) { cout << arry[i] << " "; } return arry; } int* test2() { int* arry2 = new int[10];//new操作符堆区开辟一块空间存储数组,注意new符号下数组的格式 for (int i = 0; i < 5; i++) { arry2[i] = i+1; } for (int i = 0; i < 5; i++) { cout << arry2[i] << " "; } cout << endl; return arry2; } int main() { //int* arry = test();//接收函数返回的地址,只是数组的首地址,但是函数执行完毕地址内的数据释放, int* arry2 = test2();//此时数据位于栈区,不会立即释放,可以打印出数组内的数据 for (int i = 0; i < 5; i++) { cout << arry2[i] << " "; } delete[] arry2;//手动释放堆区内存 system("pause"); return 0; }
3、引用
#includeusing namespace std; int main() { int a = 10; cout << a << endl; int& b = a; b = 20; cout << a << endl; //应用的注意事项 //引用必须初始化,引用初始化后不可更改,即一个别名只能对应一个内存不可再对应其他内存 system("pause"); return 0; }
引用做函数参数
#includeusing 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 << " b=:" << b << endl; swap(a,b); cout << "转换后" << "a=:" << a << " b=:" << b << endl; system("pause"); return 0; }
引用做函数返回值
#includeusing namespace std; //返回引用 int& test1() { int a = 10; return a; } //将test1的局部变量变为全局变量 int& test2() { static int a = 10; return a; } int* test3() { static int a = 10; return &a; } int main() { //int& p1 = test1(); int& p1 = test2(); cout << p1 << endl; cout << "1" << endl; cout << p1 << endl;//局部变量的引用不能返回,改成全局变量即可返回 test2() = 1000;//函数返回引用作为左值,注意静态变量也可以进行赋值 int& p2 = test2(); cout << p2 << endl; int* p3 = test3();//引用可用指针返回 cout << *p3 << endl; system("pause"); return 0; }
引用的本质以及常量引用
#includeusing namespace std; void test(const int& a) { //a = 20;加入形参的const防止误修改 } int main() { //引用的本质 int a = 10; int& b = a; //int* const b=&a;实质为创建一个常量指针 //使用引用时,自动对指针进行解引用操作 //常量引用 test(a); system("pause"); return 0; }
4 、函数—默认参数和占位参数
#includeusing namespace std; //默认参数 //注意点-如下有三个传入参数时,若第一个或第二个为默认参数,则后面的参数必须要有默认参数 //注意点-分开编写时函数定义和声明只能有一块有默认参数 int test1(int a, int b = 10, int c = 10);//声明默认 int test1(int a, int b , int c )//定义不默认 { return a + b + c; } //占位参数 void test2(int a, int)//占位参数可以为默认值,void test2(int a,int=10) { cout << "占位参数函数" << endl; } int main() { int a = 20; int sum = test1(a); cout << sum << endl; test2(10, 10);//占位参数不默认时必须传入相应类型的数据 system("pause"); return 0; }
函数重载
#includeusing namespace std; //函数重载条件 //函数名相同,参数个数不同或类型不同或顺序不同 //不能按返回值类型进行函数重载 //函数重载一定避免默认值的使用 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 main() { func(); func(10); func(3.14); func(10,3.14); func(3.14, 10); system("pause"); return 0; }
5、类和对象—封装
//类和对象,封装 //类中的成员—变量,行为—函数 #includeusing namespace std; #define pi 3.14 //创建类 class Circle { public://访问权限,公共和私有和保护,此处显示class和struct的区别,class为默认私有权限,struct默认公共权限 //成员 int m_r ; //行为 double CalculateC() { return 2 * pi * m_r; } }; class Student { public: //成员 string m_name; int m_id; //行为 void setid(int num) { m_id = num; } void setname(string name) { m_name = name; } void showstudent() { cout << "学生姓名:" << m_name << "学生学号:" << m_id << endl; } }; class Person { public: string m_name; private: int money; protected: string car; public: void func() { m_name = "张三"; money = 123; car = "qq"; } }; int main() { //类的实例化 Circle c; c.m_r = 10; cout << "周长:" << c.CalculateC() << endl; Student s; s.m_id = 1; s.m_name = "张三"; s.setid(1); s.setname("张三"); s.showstudent(); Person p; p.m_name = "李四";//只能修改姓名即在公共区域内的值 system("pause"); return 0; }
封装—成员属性私有化
#includeusing namespace std; class Person { //所谓私有属性设置就是将成员都设置在私有权限内,再通过公共权限内的行为设置对私有权限内的成员进行读取操作 private://私有属性设置三个成员都不能直接进行赋值操作 string m_name; int m_age; string m_lover; public: void setname(string name)//姓名写入 { m_name = name; } string getname()//姓名读出 { return m_name; } void setage(int age)//年龄写入 { m_age = age; } int getage()//年龄读出 { return m_age; } void setlover(string lover)//情人仅可设置为写入 { m_lover = lover; } }; int main() { Person p; p.setname("张三"); cout << "姓名:" << p.getname() << endl; p.setage(20); cout << "年龄:" << p.getage() << endl; p.setlover("李四"); system("pause"); return 0; }
封装—案例1立方体
#includeusing namespace std; 立方体类设计 1、属性,长、宽、高 2、行为,面积和体积 3、分别用全局函数和成员函数判断两立方体是否相等 class Cube { public: int m_l; int m_w; int m_h; int CalculateS() { return 2 * m_l * m_w + 2 * m_l * m_h + 2 * m_w * m_h; } int CalculateV() { return m_l * m_w * m_h; } void issame(Cube& c1) { if (c1.m_h == m_h && c1.m_l == m_l && c1.m_w == m_w) { cout << "两立方体相等" << endl; } else { cout << "两立方体不相等" << endl; } } }; //全局函数判断是否相等 void issame(Cube c1,Cube c2) { if (c1.m_w == c2.m_l && c1.m_h == c2.m_h && c1.m_w == c2.m_w) { cout << "两立方体相等" << endl; } else { cout << "两立方体不相等" << endl; } } int main() { Cube c1; c1.m_l = 10; c1.m_w = 10; c1.m_h = 10; cout << "c1的面积:" << c1.CalculateS() << endl; cout << "c1的体积:" << c1.CalculateV() << endl; Cube c2; c2.m_w = 10; c2.m_l = 10; c2.m_h = 10; cout << "c2的面积:" << c2.CalculateS() << endl; cout << "c2的体积:" << c2.CalculateV() << endl; //issame(c1, c2); c2.issame(c1); system("pause"); return 0; }
封装—案例2点和圆的关系
#includeusing namespace std; class Point { private: int m_x; int m_y; public: //设置x void setx(int x) { m_x = x; } //获取x int getx() { return m_x; } //设置y void sety(int y) { m_y = y; } //获取y int gety() { return m_y; } }; class Circle { private: int m_r; Point m_center; public: //设置r void setr(int r) { m_r = r; } //获取r int getr() { return m_r; } //设置圆心 void setcenter(Point center) { m_center = center; } //获取圆心 Point getcenter() { return m_center; } }; void incircle(Point p, Circle c) { int dis = sqrt((p.getx() - c.getcenter().getx()) * (p.getx() - c.getcenter().getx()) + (p.gety() - c.getcenter().gety()) * (p.gety() - c.getcenter().gety())); if (dis == c.getr()) { cout << "点在圆上" << endl; } else if (dis < c.getr()) { cout << "点在圆内" << endl; } else { cout << "点在圆外" << endl; } } int main() { Point p; p.setx(20); p.sety(10); Point center; center.setx(10); center.sety(10); Circle c; c.setr(10); c.setcenter(center); incircle(p, c); system("pause"); return 0; }



