C++练习_基础练习

C++基础练习

基本概念

  • 面向对象:封装、继承、多态->应付需求变化能力->如何解耦合度

  • C++相关编译文件 : g++ .cpp .h .hpp

  • 命名空间:独立于全局的作用域
    C中函数都写在全局,不可以重名,而C++中的命名空间中的函数名可以和全局的函数一样

using name::func;
func(); //调用name命名空间下的func()

::func(); //省略命名空间表示全局的函数

  • this :指向调用它的类的指针
    私有成员的修改,使用公开的成员函数修改

  • 写类时的规则:
    1)讲究合理
    2)高内聚,每一个类必须只做自己的事情,最抽象简单化
    3)防止因为参数意想不到的变化而产生错误
    4)变量全部使用private,修改的函数放在public,对输入的变量进行控制
    5)接口要隔离,细化到单元操作,比如只修改坐标x
    6)const:函数参数中有const则表明不会更改其值,不加则表示会更改

  • 构造函数
    1.可以创建多个,参数要不同,参数适配(初始化时调用)
    2.可以看作初始化函数
    3.构造函数内可以直接调用成员函数
    4.构造函数内最好不要使用cin,会出现莫名错误

class Base{
	public:
		Base(void){;}
		Base(int a, int b){;} //带参构造函数
};
	//初始化
	Base base1 = Base::Base(1,2);
	//或者 
	Base base1(1,2);

列表初始化:

  • 真正的初始化,在实例创建完成之前,可以用来初始化内部变量参数
  • 注意:需要按照参数定义的顺序初始化,不然会报错
point(void) :x(0),y(0) {}
//C++列表初始化,真正的初始化,在实例创建完成之前,可以用来初始化内部变量参数
		
int a(1); 初始化相当于 int a=1;
可以这样初始化int变量
int a(1),b(2);
cout<<a<<b;

class Student{
	private:
		int score;
		char sex[SEX_SIZE];
		char name[NAME_SIZE];
		
Student::Student()
	:score(0),sex("\0"),name("\0")
	// :name("\0"),sex("\0"),score(0) 没有按顺序初始化就会报错哦
  • 重载函数:
    只用一个点,使用重载运算符和重载函数:
    C++可以重定义或重载大部分 内置的运算符。这样,您就能使用自定义类型的运算符。

重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);

‘&’:引用变量是一个别名,也就是说,它是某个已存在变量的另一个名字。一旦把引用初始化为某个变量,就可以使用该引用名称或变量名称来指向变量。

练习

题1:求两个点的距离

使用嵌套:使用指针,做到点与线的隔离

/*
 * coordinate.cpp
 * 
 * 
 */


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

class point
{
	private:
		int x;
		int y;
		
	public:
	//构造函数1
		point(void)
			:x(0),y(0)
		{}
		//构造函数2
		point(int num){
			printf("创建点%d 坐标:",num);
			cin >> x >>y; //不推荐
		}

		int getX(){return x;}
		int getY(){return y;}
		
		void setX(int x){this->x = x;}
		void setY(int y){this->y = y;}
		void setpoint(int x, int y){
			setX(x);
			setY(y);
		}
};

class Line
{
	private:
		point* point1;
		point* point2;
	public:
		Line(){ //构造函数,创建对象时自动调用。
			cout << "创建一个线段" << endl ;
		}
	
		void setlineHEAD(point* head){this->point1 = head;}
		void setlineEND(point* end){this->point2 = end;}
		
		double getlength(){
			return 
			sqrt(pow((this->point1->getX() - this->point2->getX()),2)
			+ pow((this->point1->getY() - this->point2->getY()),2));
		}
};

int main(int argc, char **argv)
{
	point point1(1);
	point point2(2);
	point point3(3);
	point point4(4);
	
	Line length;
	
	length.setlineHEAD(&point1);
	length.setlineEND(&point2);
	printf("线段1-2长度为:%.2f\n",length.getlength());
	
	length.setlineHEAD(&point1);
	length.setlineEND(&point3);
	printf("线段1-3长度为:%.2f\n",length.getlength());
	
	length.setlineHEAD(&point1);
	length.setlineEND(&point4);
	printf("线段1-4长度为:%.2f\n",length.getlength());
	
	length.setlineHEAD(&point2);
	length.setlineEND(&point3);
	printf("线段2-3长度为:%.2f\n",length.getlength());
	
	 
	return 0;
}


输出:

创建点1 坐标:1 1
创建点2 坐标:2 2
创建点3 坐标:3 3
创建点4 坐标:4 4
创建一个线段
线段1-2长度为:1.41
线段1-3长度为:2.83
线段1-4长度为:4.24
线段2-3长度为:1.41

使用继承和重载:

/*
 * coordinate.cpp
 * 
 * 
 */


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

class point
{
	public:
		int x;
		int y;
		
		void setpoint();
};


class Coordinate_opt: public point
{
	public:
	//将'*'定义为求两点距离,operator为关键字,'&'为引用
	double operator *(const Coordinate_opt& coord)
	{
		return sqrt(pow((this->x-coord.x),2)+pow((this->y-coord.y),2));
	}
		//others
		
};

void point::setpoint()
{
	cout << "输入第一个点:";
	cin >> this->x >> this->y;
}


int main(int argc, char **argv)
{
	Coordinate_opt opt1;
	Coordinate_opt opt2;
	opt1.setpoint();
	opt2.setpoint();
	cout<<"length:"<<opt1*opt2<<endl;
	return 0;
}


题2:
定义一个5个成员的数组,从键盘录入连续从键盘录入5个数据,3,6,9,12,15,给出比较友好的提示,并打印输出。
使用引用修改数组某个值

/*
 * 1_test.cpp
 * 1:定义一个5个成员的数组,从键盘录入连续从键盘录入5个数据,3,6,9,12,15,给出比较友好的提示,并打印输出。
 */


#include <iostream>
using namespace std;

#define SIZE 5

class Myarray
{
	private:
		int array[SIZE];
	public:
		Myarray(void);
		void setarry();
		void printarry();
		int& setvalue(int i);
};

Myarray::Myarray(void)
{
	setarry();
}

void Myarray::setarry()
{
	for(int i=0; i<SIZE; ++i){
		printf("Value for Myarray[%d]: ",i);
		cin >> array[i];
	}
}

int& Myarray::setvalue(int i)
{
	int& ref = array[i];
	return ref;
}

void Myarray::printarry()
{
	cout<<"输出数组:\n";
	for(int i=0; i<SIZE; ++i){
		printf("Myarray[%d]: %d\n",i,array[i]);
	}
}

int main(int argc, char **argv)
{
	Myarray myarray;
	myarray.printarry();
	cout<<"请输入需要修改的下标和修改的值:";
	int index(0),num(0);
	cin>>index>>num;
	myarray.setvalue(index)=num;
	myarray.printarry();
	return 0;
}


输出:

Value for Myarray[0]: 3
Value for Myarray[1]: 6
Value for Myarray[2]: 9
Value for Myarray[3]: 12
Value for Myarray[4]: 15
输出数组:
Myarray[0]: 3
Myarray[1]: 6
Myarray[2]: 9
Myarray[3]: 12
Myarray[4]: 15
请输入需要修改的下标和修改的值:0 100
输出数组:
Myarray[0]: 100
Myarray[1]: 6
Myarray[2]: 9
Myarray[3]: 12
Myarray[4]: 15

题3:

/*
 * 2_test.cpp
 * 2.设计一个学生类,要求该类有姓名、成绩、性别三个属性以及自我介绍的成员函数
 */


#include <iostream>

#define SEX_SIZE 4
#define NAME_SIZE 20

using namespace std;

class Student{
	private:
		int score;
		char sex[SEX_SIZE];
		char name[NAME_SIZE];
	public:
		Student() :score(0),sex("\0"),name("\0"){}
		
		void init(){setname();setsex();};
		
		char* getname(){return name;}
		char* getsex(){return sex;}
		int getscore(){return score;}
		
		void setname(){
			cout<<"请输入名字:";
			cin>>this->name;
		}
		void setsex(){
			cout<<"请输入性别:";
			cin>>this->sex;
		}
		void setscore(int num){
			if(num>100)num=100;
			if(num<0)num=0;
			score = num;
		}
		void introduce(){
			cout<<"姓名:"<<name<<" 性别:"<<sex
			<<" 成绩:"<<score<<endl;
		}
};

int main(int argc, char **argv)
{
	Student student;
	student.init();
	student.introduce();
	
	cout<<"输入学生成绩:";
	int score(0);
	cin>>score;
	student.setscore(score);
	
	student.introduce();
	return 0;
}


输出:

请输入名字:徐文涵
请输入性别:男
姓名:徐文涵 性别:男 成绩:0
输入学生成绩:100
姓名:徐文涵 性别:男 成绩:100

题4:

/*
 * 3_test.cpp
设计一个分数类  Fraction
数据成员:
这个类包含  分子  分母
成员函数:
       1.通过setFraction函数,设置 分子和分母的值
       2.打印分式   print()  形式:2 / 3
       3.约分    redu()  12 / 16   ---->  3 / 4
       约分思路:
       从后先前遍历,第一能同时被12和16整除的数
       一定是 它们的最大公约数
 */


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

class Fraction{
	private:
		int denominator;
		int numerator;
	public:
		Fraction() :denominator(0),numerator(0) {}
		
		void setFraction(int de,int nu){
			if(de==0){cout<<"分母不可以为0!\n";return;}
			if(de<0&&nu<0)de=fabs(de),nu=fabs(nu);
			denominator = de;
			numerator = nu;
		}
		void print(){
			if(!(numerator<0&&denominator<0) && (numerator<0 || denominator<0))
			cout<<" - "<<fabs(numerator)<<" / "<<fabs(denominator)<<endl;
			else cout<<numerator<<" / "<<denominator<<endl;
		}
		void redu(){
			int max=0,min=0,flag=0;
			fabs(denominator)>fabs(numerator)?(max=denominator,min=numerator,flag=0):(min=denominator,max=numerator,flag=1);
			int i=0;
			if(min<0){i=min-1;while(++i)if(!(max%i || min%i) ){max/=i,min/=i;break;}}
			if(min>0){i=min+1;while(--i)if(!(max%i || min%i) ){max/=i,min/=i;break;}}
			if(flag){denominator=min,numerator=max;}
			else {denominator=max,numerator=min;}
		}
};



int main(int argc, char **argv)
{
	Fraction fraction;
	int de,nu;
	cout<<"输入分数: ";
	//cin>>nu>>de;
	fscanf(stdin,"%d",&nu);getchar();fscanf(stdin,"%d",&de);
	fraction.setFraction(de,nu);
	cout<<"输入分子和分母为: ";
	fraction.print();
	fraction.redu();
	cout<<"化简后: ";
	fraction.print();
	return 0;
}


输出:

输入分数: -88/-44
输入分子和分母为: 88 / 44
化简后: 2 / 1


  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值