目录
9、结构体的练习2(功能为输出3个老师带的5个学生的成绩,每个学生的成绩随机生成。)
10、结构体练习3(创建一个有姓名、年龄、性别的结构体,创建英雄数组输入5个英雄、然后通过冒泡排序对年龄进行降序排列,最后输出全部)
2022.04.27
1、冒泡排序的练习
#include<iostream>
using namespace std;
//由高到低
int main()
{
int temp;
int arr[9] = {1,2,3,4,5,6,7,8,9};
for (int i=8;i>=0;i--)
{
for (int j = i - 1; j >= 0; j--)
{
if (arr[j] > arr[i])
{
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
cout << arr[i] << endl;//i是倒着来的,先输出arr【8】后arr【7】...
}
system("pause");
return 0;
}
2、时钟类的练习
封装的意义:将属性和行为作为一个整体,表现生活中的事物、将属性和行为加以权限控制
#include<iostream>
using namespace std;
class Clock
{
public:
void settime(int newH, int newM, int newS)
{
hour = newH;
minute = newM;
second = newS;
}
void showtime()
{
cout <<"现在的时间是" <<hour << ":" << minute << ":" << second << endl;
}
private:
int hour, minute, second;
};
int main()
{
Clock myclock;
cout << "现在时间为" << endl;
myclock.settime(0, 0, 0);
myclock.showtime();
cout << "第一次调试时间" << endl;
int a, b, c;
cout << "请输入小时" << endl;
cin >> a;
cout << "请输入分钟" << endl;
cin >> b;
cout << "请输入秒数" << endl;
cin >> c;
myclock.settime(a, b, c);
myclock.showtime();
system("pause");
return 0;
}
3、时钟类的升级版(具备判断用户输入的时间是否正确的功能)
#include<iostream>
using namespace std;
class Clock
{
public:
void settime(int newH, int newM, int newS)
{
hour = newH;
minute = newM;
second = newS;
}
void showtime()
{
cout << "现在的时间是" << hour << ":" << minute << ":" << second << endl;
}
private:
int hour, minute, second;
};
int main()
{
Clock myclock;
cout << "现在时间为" << endl;
myclock.settime(0, 0, 0);
myclock.showtime();
cout << "第一次调试时间" << endl;
int a, b, c;
cout << "请输入小时(24小时制)" << endl;
cin >> a;
while (a < 0 || a > 23)
{
cout << "请输入正确的小时" << endl;
cin >> a;
}
cout << "请输入分钟" << endl;
cin >> b;
while (b < 0 || b > 59)
{
cout << "请输入正确的分钟" << endl;
cin >> b;
}
cout << "请输入秒数" << endl;
cin >> c;
while (c < 0 || c > 59)
{
cout << "请输入正确的秒数" << endl;
cin >> c;
}
myclock.settime(a, b, c);
myclock.showtime();
system("pause");
return 0;
}
现在程序有个bug,就是当输入小数的时候会出错。可以在先将a声明为浮点型,在while条件语句中加入abs(a-(int)a!=0)的情况(abs为取绝对值的符号),【但在这里因为a是正数,所以可以不用取绝对值,a恒>=(int)a,】这样就可以解决这一问题。
float a,b,c;
while (a < 0 || a > 23||a-(int)a!=0)
while (b < 0 || b > 59||b-(int)b!=0)
while (c < 0 || c > 59||c-(int)c!=0)
2022.04.28
4、泳池类
#include<iostream>
using namespace std;//利用类求出泳池、过道的面积
float PI = 3.14;
class circle {
public:
circle(float r);
float C() {
return 2 * PI * radius;//类内可以互访,类外不可以访问private。
}
float S() {
return radius * radius * PI;
}
private:
float radius;
};
circle::circle(float r) {
radius = r;
}
int main()
{
float radius;
float distence;
cout << "请输入大圆的半径" << endl;
cin >> radius;
cout << "请输入大圆与泳池间的距离" << endl;
cin >> distence;
circle pool(radius);
circle middle(radius - distence);
cout << "大圆的周长为" << pool.C()<<endl;
cout << "大圆的面积为" << pool.S()<< endl;
cout << "过道的面积为" << pool.S()-middle.S() << endl;
cout << "中间泳池的面积为" << middle.S() << endl;
cout << "中间泳池的周长为" << middle.C() << endl;
system("pause");
return 0;
}
5、利用数组统计学生成绩
#include<iostream>
using namespace std;
#include<string>
int main()
{
int arr[3][3] =
{
{60,60,70},{80,60,90},{85,85,85}
};
int zongfen[3];
string name[3] = {"张三","李四","王五"};//不要忘记包含string头文件
for (int i = 0; i < 3; i++)//求每个人的总分
{
int sum = 0;
for (int j = 0; j < 3; j++)
{
sum += arr[i][j];
}
zongfen[i] = sum;
}
//用冒泡排序对总分进行由高到低排序
for (int a = 2; a >= 0; a--)
{
for (int b = a - 1; b >= 0; b--)
{
if (zongfen[a] > zongfen[b])
{
int temp = zongfen[b];
zongfen[b] = zongfen[a];
zongfen[a] = temp;
}
}
}
for (int i = 0; i <=2; i++)
{
cout << name[i] << "的成绩为" << zongfen[i] << ",排名为 " << i + 1 << endl;
}
system("pause");
return 0;
}
6、利用数组统计学生成绩(改版1:输入名字查询总分)
#include<iostream>
using namespace std;
#include<string>
int main()
{
int arr[3][3] =
{
{60,60,70},{80,60,90},{85,85,85}
};
int zongfen[3];
string name[3] = {"张三","李四","王五"};
for (int i = 0; i < 3; i++)//求每个人的总分
{
int sum = 0;
for (int j = 0; j < 3; j++)
{
sum += arr[i][j];
}
zongfen[i] = sum;
}
//用冒泡排序对总分进行由高到低排序
for (int a = 2; a >= 0; a--)
{
for (int b = a - 1; b >= 0; b--)
{
if (zongfen[a] > zongfen[b])//gaodao低
{
int temp = zongfen[b];
zongfen[b] = zongfen[a];
zongfen[a] = temp;
}
}
}
cout << "请输入你的名字" << endl;
string x;
cin >> x;
while (x != "张三"&& x != "李四" && x != "王五")
//易错点:是&&而不是||,若是||则至多满足一个条件,至少有两个条件无法满足,则无论你输入啥,都提醒你输错了。
{
cout << "你不是本班同学,或者请你检查输入的名字是否有误" << endl;
cin >> x;
}
if (x == "张三")
{
cout << x << "同学,你的成绩为" << zongfen[1] <<",排名第2" <<endl;
}
else if (x == "李四")
{
cout << x << "同学,你的成绩为" << zongfen[2] << ",排名第3" << endl;
}
else if (x == "王五")
{
cout << x << "同学,你的成绩为" << zongfen[0] << ",排名第1" << endl;
}//排名为数组下标加1,
system("pause");
return 0;
}
缺陷:
1、排名暂时没想到怎么智能给出,虽然人为手输可以在结尾加个排名,但是当一个班有60个学生时,这并不现实。
但是第五个练习(5、利用数组统计学生成绩)也就是未改版的可以智能输出全班(不论多少人,只需导入名字跟成绩即可)的总分和排名。
晚点看看能不能想个办法将二者结合。
2022.04.29-30
7、点类和圆类的练习(判断点是否在圆上)
#include<iostream>
using namespace std;
class point
{
public:
int newx = 0;
int newy = 0;
void setpoint()//如果这里newx、newy没有赋初值,那么下面调用函数的时候就会提醒说使用的参数太少了。
{
cout << "请输入点的横坐标" << endl;
cin >> newx;
x = newx;
cout << "请输入点的纵坐标" << endl;
cin >> newy;
y = newy;
}
void setcenter()
{
cout << "请输入圆心的横坐标" << endl;
cin >> newx;
x = newx;
cout << "请输入圆心的纵坐标" << endl;
cin >> newy;
y = newy;
}
void showpoint()
{
cout << "该点的坐标为(" << x << "," << y << ")" << endl;
}
private:
int x, y;
};
class circle
{
public:
point center;
int r;
void setr()
{
cout << "请输入圆的半径" << endl;
cin >> r;
R = r;
}
private:
int R;
};
int main()
{
cout << "该程序将判断点与圆的关系" << endl;
point p1;
p1.setpoint();
p1.showpoint();
circle yuan1;
yuan1.center.setcenter ();
yuan1.setr ();
int d = (p1.newx - yuan1.center.newx)*( p1.newx - yuan1.center.newx)+(p1.newy - yuan1.center.newy) * (p1.newy - yuan1.center.newy);
if (d == yuan1.r * yuan1.r)
{
cout << "点在圆上" << endl;
}
else if (d < yuan1.r * yuan1.r)
{
cout << "点在圆内" << endl;
}
else if (d > yuan1.r * yuan1.r)
{
cout << "点在圆外" << endl;
}
system("pause");
return 0;
}
2022.05.01
8、结构体的练习
#include<iostream>
using namespace std;
#include <string>
struct student
{
string name;
int age;
int sorce;
};
struct teacher
{
string name;
int age;
student s1;
};
void show(teacher * t1)
{
cout << t1->name << "的年龄为" << t1->age << ",他的学生为" << t1->s1.name << ",年龄为" << t1->s1.age << ",成绩为" << t1->s1.sorce << endl;
}
int main()
{
student s1 = { "张三",18,80 };
teacher t1 = { "老王",50,s1 };
show(&t1);
system("pause");
return 0;
}
笔记:1、结构体属于用户自定义的数据类型,指针的语法为【数据类型*指针名】
2、除了结构体定义处struct不可省略,其他地方可以省略,直接输入自定义的数据类型即可使用
3、指针访问要用"->"
4、值传递占用内存空间大(因为值传递拷贝了一个对象的所有数据),而地址传递的指针只占4字节?)但是地址传递有可能会误改原来的值,不想误改的话指针要用常量指针。
9、结构体的练习2(功能为输出3个老师带的5个学生的成绩,每个学生的成绩随机生成。)
#include<iostream>
using namespace std;
#include<string>
#include<ctime>
struct student
{
string name;
int sorce;
};
struct teacher
{
string name;
student s[5];
};
void setname(teacher tarr[], int len)
{
string nameseed = "ABCDE";
for (int j = 0; j < len; j++)
{
tarr[j].name = "Teacher_";
tarr[j].name += nameseed[j];
for (int i = 0; i < 5; i++)
{
int random = rand() %101;//注意放在循环体内才能每次重新随机生成,范围为0-100.
tarr[j].s[i].name = "Student_";
tarr[j].s[i].name += nameseed[i];
tarr[j].s[i].sorce = random;
}
}
}
void show(teacher tarr[],int len)
{
for (int a = 0; a < len; a++)
{
cout << tarr[a].name << " 所带的学生为" << endl;
for (int b = 0; b < 5; b++)
{
cout <<"\t学生姓名为" << tarr[a].s[b].name << " 分数为" << tarr[a].s[b].sorce << endl;
}
}
}
int main()
{
srand((unsigned int)time(NULL));//由系统时间生成随机数字(随机种子)
teacher tarr[3];
int len = sizeof(tarr) / sizeof(tarr[0]);
setname(tarr,len);
show(tarr, len);
system("pause");
return 0;
}
输出结果:
2022.05.02
10、结构体练习3(创建一个有姓名、年龄、性别的结构体,创建英雄数组输入5个英雄、然后通过冒泡排序对年龄进行降序排列,最后输出全部)
#include<iostream>
using namespace std;
#include<string>
struct hero
{
string name;
int age;
string sex;
};
int main()
{
hero arr[5] = { {"刘备",95,"男"} ,{"关羽",43,"男"} , {"张飞",3,"男"} , {"赵云",38,"男"} , {"貂蝉",18,"女"} };
for (int i = 4; i >=0; i--)
{
for (int j = i - 1; j >= 0; j--)
{
if (arr[j].age > arr[i].age)
{
int temp = arr[j].age;
arr[j].age = arr[i].age;
arr[i].age = temp;
string tempname = arr[j].name;
arr[j].name = arr[i].name;
arr[i].name = tempname;
string tempsex = arr[j].sex;
arr[j].sex = arr[i].sex;
arr[i].sex = tempsex;
}
}
cout << arr[i].name <<" "<<arr[i].age << " " << arr[i].sex << endl;
}
system("pause");
return 0;
}
这个方法比较笨,也很麻烦,冒泡排序需要9行才完成整个数组元素的交换,当一个英雄元素较多的时候很麻烦。
11、结构体练习3的改进(地址传递)
#include<iostream>
using namespace std;
#include<string>
struct hero
{
string name;
int age;
string sex;
};
void change(hero arr[])
{
for (int i = 4; i >= 0; i--)
{
for (int j = i - 1; j >= 0; j--)
{
if (arr[j].age > arr[i].age)
{
hero temp = arr[j];
arr[j] = arr[i];
arr[i] = temp;
}
}
cout << arr[i].name << " " << arr[i].age << " " << arr[i].sex << endl;
}
}
int main()
{
hero arr[5] = { {"刘备",95,"男"} ,{"关羽",43,"男"} , {"张飞",3,"男"} , {"赵云",38,"男"} , {"貂蝉",18,"女"} , };
change(arr);
system("pause");
return 0;
}
2022.05.05
12、如何调用函数内定义的变量(引用的知识)
一般方法是无法在离开了函数作用域后调用函数内定义的变量的,是因为执行完函数的代码后,系统自动调用了析构函数,变量的内存就会被释放掉,程序员就无法再使用。
但是可以使用引用的方法
#include<iostream>
using namespace std;
//使用函数调用的方法使n自增5次
int & fn1()
{
static int n=0;
n++;
return n;
}
int main()
{
for (int i = 4; i > 0; i--)
{
fn1();
}
int& n1 = fn1();
cout << "n的值为 " << n1<< endl;
system("pause");
return 0;
}
13、利用模板实现通用数组操作
myarr.hpp
#pragma once
#include<iostream>
using namespace std;
template<class T>//T是指数组的数据类型
class myarr
{
public:
//构造函数
myarr(int capacity)
{
this->m_capacity = capacity;
this->m_size = 0;
this->arr = new T[this->m_capacity];//深拷贝,防止指针重复释放。
}
//析构函数
~myarr()
{
if (this->arr != NULL)
{
delete[] this->arr;
this->arr = NULL;//防止野指针
}
}
//拷贝构造
myarr(const myarr& p)
{
this->m_capacity = p.m_capacity;
this->m_size = p.m_size;
//深拷贝:
this->arr = new T[p.m_capacity];
for (int i = 0; i < this->m_size; i++)
{
this->arr[i] = p.arr[i];
}
}
//=重载,也是防止浅拷贝问题。
myarr & operator=(const myarr&p1)//加了&可以作为左值。
{
//判断是否有数据,有的话先清空再赋值。
if (this->arr != NULL)
{
delete[]this->arr;
this->arr = NULL;
this->m_capacity = 0;
this->m_size = 0;
}
this->m_capacity = p1.m_capacity;
this->m_size = p1.m_size;
this->arr = new T[this->m_capacity];
for (int i = 0; i < this->m_size; i++)
{
this->arr[i] = p1.arr[i];
}
return *this;//返回自身。
}
//通过下标的方式来访问数据。 重载[]
T& operator[](int index)
{
return this->arr[index];
}
//返回数组容量
int getCapacity()
{
return this->m_capacity;
}
//返回数组大小
int getSize()
{
return this->m_size;
}
//尾插法
void back(const T& p)
{
if (this->m_size == this->m_capacity)
{
return;
}
this->arr[this->m_size] = p;
this->m_size++;
}
private:
int m_capacity;
int m_size;
T* arr;
};
.cpp
#include<iostream>
using namespace std;
#include<string>
#include"myarr.hpp"
class person//自定义person类。
{
public:
//不要漏了默认构造:因为自己写的有参构造会覆盖默认构造,所以还要自己再写个默认构造才可以。
person(){}
person(int age,string name)//有参构造函数
{
this->m_age = age;
this->m_name = name;
}
int m_age;
string m_name;
};
void printarr(myarr<int>arr1)
{
for (int i = 0; i < 5; i++)
{
arr1.back(i);
cout << arr1[i] << endl;
}
cout << "数组容量:" << arr1.getCapacity() << endl;
cout << "数组大小:" << arr1.getSize() << endl;
}
void test01()
{
//test01:
myarr<int> arr1(5);
printarr(arr1);
//arr2若能能成功运行,证明深拷贝,没问题。
myarr<int> arr2(arr1);//对象由另一个对象进行初始化。调用了拷贝构造
printarr(arr2);
}
int main()
{
test01();
cout << endl;
cout << "test02:" << endl;
myarr<person>arr3(3);
person p1(12,"张三");
arr3.back(p1);
cout << "姓名:" << arr3[0].m_name << " 年龄:" << arr3[0].m_age << endl;
cout << "数组容量:" << arr3.getCapacity() << endl;
cout << "数组大小:" << arr3.getSize() << endl;
system("pause");
return 0;
}
运行结果: