C++程序设计-第6周 const用法及指针数据成员

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565


第一部分 阅读程序

阅读程序,可以在上机时通过单步执行进一步和你在人脑中运行程序的过程进行对照。

a.阅读程序,写出程序的运行结果并理解
#include <iostream>
using namespace std;
class base
{
private:
  int m;
public:
  base(){};
  base(int a)  {m=a; }
  int get(){return m;}
  void set(int a){m=a;}
};//base_end

int main()
{
  base *ptr;
  ptr=new base[2];  
  ptr->set(30);
  ptr=ptr+1;
  ptr->set(50);
  base a[2]={1,9};
  cout<<a[0].get()<<","<<a[1].get()<<endl;
  cout<<ptr->get()<<",";
  ptr=ptr-1;
  cout<<ptr->get()<<endl;
  delete[] ptr;
  Return 0;
}

b.阅读程序,写出程序的运行结果并理解
#include<iostream>
using namespace std;
class CE 
{
private:
  int a,b;
  int getmin() {return (a<b? a:b);}
public:
  int c;
  void SetValue(int x1,int x2, int x3)
  {
    a=x1; b=x2; c=x3;
  }
  int GetMin();
};
int CE::GetMin() 
{
  int d=getmin();
  return (d<c? d:c);
}
int main()
{
  int x=5,y=12,z=8;
  CE *ep;
  ep=new CE;
  ep->SetValue(x+y,y-z,10);
  cout<<ep->GetMin()<<endl;
  CE a=*ep;
  cout<<a.GetMin()*3+15<<endl;
  return 0;
}

c. 阅读程序,写出程序的运行结果并理解
#include <iostream>
using namespace std;
class Time
{
public:
  Time(int,int,int);
  int hour;
  int minute;
  int sec;
  void output_time( );  
};
Time::Time(int h,int m,int s)
{
  hour=h;
  minute=m;
  sec=s;
}


void Time::output_time( )  
{
   cout<<hour<<":";
   cout<<minute<<":" <<sec<<endl;
}


int main( )
{
  Time t1(10,13,56); 
  int *p1=&t1.hour; //指向数据成员的指针
  cout<<*p1<<endl; 
  t1.output_time( ); 
  
  Time *p2=&t1; //指向对象的指针
  p2->output_time( ); 


  void (Time::*p3)( ); //指向成员函数的指针 
  p3=&Time::output_time;  
  (t1.*p3)( ); 
  return 0;
}

d. 阅读下面的程序,在横线上写出注释来,并品味和学会这些写法
思考:为什么此处对数据成员a要动态分配存储空间?不这样做,会有什么后果?请试着将你的答案写在本页空白处。提示:可以删除(3)行的语句看看会发生什么现象。
#include<iostream>
#include<stdlib.h>
using namespace std;
class A 
{
private:
  char *a;
public:
  A():a(NULL){} //(1)___________________________________________
  A(char *aa) {
    a=new char[strlen(aa)+1];  //(2)___________________________________________
    strcpy(a,aa);  //(3)____________________________________________
  }
  ~A() {delete []a;} //(4)___________________________________________
  void output(){cout<<a<<endl;}
};
int main()
{
  A a("good morning, code monkeys!");
  a.output();
  return 0;
}

e. 请写出每一处const出现处的语法现象名及其所起的作用
#include <iostream>; 
#include <string>; 
using namespace std; 
class Student 
{
public: 
  Student() {} 
  Student( const string& nm, int sc = 0 ): name( nm ), score( sc ) {} 
  void set_student( const string& nm, int sc = 0 ) //(1)_________________________________
   { name = nm;  score = sc; } 
  const string& get_name() const  { return name;} //(2)_________________________________
  int get_score() const {return score;  } 
private:
  string name;
  int score;
}; 
// output student's name and score 
void output_student(const Student& student ) //(3)_________________________________
{
  cout << student.get_name() << "\t"; 
  cout << student.get_score() << endl; 
} 
int main() 
{
  Student stu( "Wang", 85 ); 
  output_student( stu ); 
  system("pause");
}

推荐“玻璃罩const”系列的三篇文章,理解const的用法:

1. 使用常对象——为共用数据加装一个名为const的玻璃罩

2. 常(const)+ 对象 + 指针:玻璃罩到底保护哪一个

3. 对象更有用的玻璃罩——常引用




第二部分 上机实践
【项目1】下面的程序存在编译错误。有两种方法可以修改,请给出这两种修改方案,在报告中说明你倾向于用哪一种?为什么?处理此类问题的原则是什么?
#include<iostream>
#include<stdlib.h>
using namespace std;
class C
{
private:
	int x;
 public:
	C(int x){this->x = x;}
	int getX(){return x;}
};
int main()
{
	const C c(5);
	cout<<c.getX();
	return 0;
}

【项目2-程序填空】按要求将缺少的代码填进去,经调试确认符合要求
a. 用指针访问对象
class A 
{
private:
	int a;
public:
	A() {a=0;}
	___(1)___{}  //定义构造函数,用参数aa初始化数据成员a
};
int main() 
{
	___(2)___;  //定义类A的指针对象p
	___(3)__;   //用p指向动态对象并初始化为整数
  return 0;
}

b. 指针类型作为成员函数的参数
class A 
{
private:
	int *a; 
	int n; 
	int MaxLen;
 public:
	A(): a(0), n(0), MaxLen(0) {}
	A(int *aa, int nn, int MM);
	~A();
	int GetValue(int i) {return a[i];} 
};
A::A(int *aa, int nn, int MM)
{
	n=nn;
	MaxLen=MM;
	if(n>MaxLen) exit(1);
	a=new int[MaxLen];
	___(1)___;  //以i为循环变量把aa数组中每个元素值传送给a数组的对应元素中
}
___(2)___   //析构函数的类外定义,释放指针型数据a所指向的空间


int main()
{
	int b[10]={1,2,3,4,5,6,7,8,9,10};
	A r(b,10,10);
	int i,s=0;
	___(3)___ ; //以i为循环变量,把r对象的a数据成员中的每个元素值依次累加到s中
	cout<<"s="<<s<<endl;
  return 0;
}

【项目3】设计平面坐标点类,计算两点之间距离、到原点距离、关于坐标轴和原点的对称点等
class CPoint
{
private:
	double x;  // 横坐标
	double y;  // 纵坐标
public:
	CPoint(double xx=0,double yy=0);
	double Distance(CPoint p) const;   // 两点之间的距离(一点是当前点,另一点为参数p)
	double Distance0() const;          // 到原点的距离
	CPoint SymmetricAxis(char style)const;//style取'x','y'和'o'分别表示按x轴, y轴, 原点对称
	void input();  //以x,y 形式输入坐标点
	void output(); //以(x,y) 形式输出坐标点
};

【项目4】设计一个三角形类,能够输入三角形的三个顶点,求出其面积、周长,并判断其是否为直角三角形和等腰三角形。
提示:(1)这个问题需要用到两个类,顶点类参照任务3中的CPoint类;(2)三角形类参考下面CTriangle类的声明;(3)充分利用CPoint类中已有的代码实现;(4)关于三条边的处理,可以增加三个私有属性,在初始化时求出来备用,也可以在需要时计算得到。
class CTriangle
{
public:
	CTriangle(CPoint &X,CPoint &Y,CPoint &Z):A(X),B(Y),C(Z){} //给出三点的构造函数
	void setTriangle(CPoint &X,CPoint &Y,CPoint &Z);//
	float perimeter(void);//计算三角形的周长
	float area(void);//计算并返回三角形的面积
	bool isRightTriangle(); //是否为直角三角形
	bool isIsoscelesTriangle(); //是否为等腰三角形
private:
	CPoint A,B,C; //三顶点
};

【项目5】将项目4用“一个项目多个文件”的方式实现,其中两个类的声明放在一个.h文件中,每个类的成员函数分别放一个文件,main()函数用一个文件。体会这样安排的优点。


【项目6】设计一个工资类(Salary),其中的数据成员包括职工人数(number,人数不定)和这些职工的工资salary,要求输入职工工资并逐个输出。
提示1:第4周项目5 数组作数据成员曾经处理过类似问题,但固定大小的数组,可能造成空间的浪费,也可能会由于空间不够而不能处理职工人数过多的应用。第4周项目5的扩展1使用指针类型的成员,通过动态分配空间解决了这一问题,但对内存空间的使用上不严谨。这个项目要求做到最终的解决。
提示2:本项目与本周第一部分“阅读程序”中的程序(d)、第二部分上机实践“项目2-程序填空”所体验的知识点相同。
部分源程序如下:
class Salary
{
public:
    Salary(int n);  //n为职工人数,初始化时完成空间的分配
    ~Salary();  //析构函数中释放初始化时分配的空间
    void input_salary();  
    void show_salary();
private:
    double *salary;
    int number;
};
//下面定义类的成员函数
……
//下面是测试函数
int main()
{
    Salary s(10);
    s.input_salary();
    s.show_salary();
    return 0;
}




上一篇:Linux工具快速上手,Linux很实用命令


下一篇:Powershell 创建炫丽美观的Html报表