c++的练习

目录

1、冒泡排序的练习

2、时钟类的练习

3、时钟类的升级版(具备判断用户输入的时间是否正确的功能)

4、泳池类

5、利用数组统计学生成绩

6、利用数组统计学生成绩(改版1:输入名字查询总分)

7、点类和圆类的练习(判断点是否在圆上)

8、结构体的练习

9、结构体的练习2(功能为输出3个老师带的5个学生的成绩,每个学生的成绩随机生成。)

10、结构体练习3(创建一个有姓名、年龄、性别的结构体,创建英雄数组输入5个英雄、然后通过冒泡排序对年龄进行降序排列,最后输出全部)

11、结构体练习3的改进(地址传递)

12、如何调用函数内定义的变量(引用的知识)

13、利用模板实现通用数组操作

myarr.hpp

.cpp


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

运行结果:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值