C++课后习题答案

参考课本:《C++面向对象程序设计》刘磊  电子科技大学出版社

第一章

1.什么是面向对象程序设计?它与传统的结构化程序设计有什么不同?

面向对象程序设计是一种以对象为中心的思维方式面向将系统看成通过交互作用来完成特定功能的对象的集合。每个对象用自己的方法来管理数据。也就是说只有对象内部的代码能够操作对象内部的数据。 

不同:面向对象有三个主要特征:封装、继承、多态

结构化程序设计由三个基本结构构成:顺序结构、选择结构、循环结构

2.在面向对象程序设计中,什么是对象?什么是类?类与对象的关系是什么?

1)对象:对象是人们要进行研究的任何事物,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。对象具有状态,一个对象用数据值来描述它的状态。对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中。

2)类:具有相同特性(数据元素)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有操作,它是对象的行为的抽象,用操作名和实现该操作的方法来描述。

类和对象的关系

类与对象的关系就如模具和铸件的关系,类的实力化的结果就是对象,而对对象的抽象就是类,类描述了一组有相同特性(属性)和相同行为的对象。

3.现实世界中的对象具有哪些特征?

任何事物都是对象。可以是一个有形的、具体存在的事物。也可以是无形的、抽象的事件

4.什么是消息?消息具有什么性质

面向对象程序设计技术必须提供一个机制允许一个对象与另一个对象的交互,这种机制称为消息传递机制。

消息的性质:

(1)同一个对象可以接受不同形式的多个消息,做出不同的响应

(2)相同形式的消息可以传递给不同的对象,所做出的响应可以是不同的

(3)对消息的响应并不是必须的

5.什么是方法?在c++中它是通过什么来实现的?

对象所能实现的行为在面向对象程序设计方法中称为方法

6.什么是抽象和封装?什么是继承?请举例说明。

抽象是将有关事物的共性归纳、集中的过程。抽象是对复杂世界的简单表示,抽象并不打算了解全部的问题,而只强调感兴趣的信息,忽略了与主题无关的信息。例如:在设计一个成绩管理程序的过程中,只关心学生的姓名、学号、成绩等,而对他的身高体重等信息就可以忽略。而在学生健康信息管理系统中,身高、体重等信息必须抽象出来,而成绩则可以忽略。
抽象是通过特定的实例抽取共同性质后形成概念的过程。面向对象程序设计中的抽象包括两个方面:数据抽象和代码抽象(或称为行为抽象)。前者描述某类对象的属性或状态,也就是此类对象区别于彼类对象的特征物理量;后者描述了某类对象的公共行为特征或具有的公共功能。
在现实世界中,所谓封装就是把某个事物包围起来,使外界不知道该事物的具体内容。在面向对象程序设计中,封装是指把数据和实现操作的代码集中起来放在对象内部,并尽可能隐蔽对象的内部细节。
下面以一台洗衣机为例,说明对象的封装特征。首先,每一台洗衣机有一些区别于其他洗衣机的静态属性。如出厂日期、机器编号等。另外,洗衣机上有一些按键,如“启动”、“暂停”、“选择”等,当人们使用洗衣机时,只需要根据需要按下“选择”、“启动”或“暂停”等按键,洗衣机就会完成相应的工作。这些按键安装在洗衣机的表面,人们通过他们与洗衣机交流,告诉它应该做什么。我们无法(也没必要)操作洗衣机的内部电路和机械控制部件,因为它们被装在洗衣机里面,这对于用户来说是隐蔽的,不可见的。

继承所表达的是类之间的相关关系,这种关系使得某类对象可以继承另外一类对象的特征和能力。现实生活中,继承是很普遍和容易理解的。例如:我们继承了父母的一些特征,如种族、血型、眼睛的颜色等,父母是我们所具有的属性的基础。
以面向对象程序设计的观点,继承所表达的是类之间相关的关系。这种关系使得某一类可以继承另一类的特征和能力。

7.传统程序设计方法的局限性主要有哪些?

(1)传统程序设计开发软件的生产效率低下
(2)传统程序设计难以应付日益庞大的信息量和多样的信息类型
(3)传统程序设计难以适应各种新环境

8. 面向对象程序设计方法的主要优点

(1)可提高程序的重用性
(2)可控制程序的复杂性
(3)可改善程序的复杂性
(4)可改善程序的可维护性
(5)能够更好地支持大型程序设计
(6)增强了计算机处理信息的范围
(7)能很好的适应新的硬件环境

第二章 

一、简答题 

1.简述c++语言的特点

1.C++在C语言基础上引入了面对对象的机制,同时也兼容C语言。
2.C++有三大特性:①封装;②继承;③多态;
3.C++语言编写出的程序结构清晰、易于扩充,程序可读性好。
4.C++生成的代码质量高,运行效率高,仅比汇编语言慢10%~20%;
5.C++更加安全,增加了const常量、引用、四类cast转换(static_cast、dynamic_cast、const_cast、reinterpret_cast)、智能指针以及try—catch等等;
6.C++可复用性高,C++引入了模板的概念,后面在此基础上,实现了方便开发的标准模板库STL(Standard Template Library)。


2.简述什么是命名空间及如何使用

命名空间
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

命名空间的使用有三种方式:
1.加命名空间名称及作用域限定符
2.使用using将命名空间中成员引入
3.使用using namespace 命名空间名称引入

3.内联函数有什么限制

1、内联函数中不可含有循环;

2、内联函数中不可含有switch语句;

3、内联函数中不可能含有静态变量;

4、内联函数不可为递归函数;

5、内联函数中不可含有错误处理。

4.函数重载有何好处

重载函数通常用来命名一组功能相似的函数,这样做减少了函数名的数量,避免了名字空间的污染,对于程序的可读性有很大的好处。

5.模板有什么作用,函数模板和模板函数有什么区别。

函数模板:函数的重载能够实现一个函数名多用,将实现相同或者相似功能的函数用同一个函数名来定义,但是在程序中仍然要分别定义每一个函数。为进一步简化,C++提供了函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表,此通用函数即为函数模板。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现不同函数的功能。
模板函数:为函数模板传参,根据实际传入的参数类型生成的一个重载函数即为模板函数,它是函数模板的一次实例化。
 

二、分析程序写结果

1.

#include
using namespace std;
void main()
{
	int* p = new int[3];
	for (int i = 0; i < 3; i++)
		p[i] = i;
	for (int i = 0; i < 3; i++)
		cout << p[i] << " ";
	cout << endl;
	p[1]++;
	cout << "p[0]=" << p[0] << ",p[1]=" << p[1] << "\n";
	delete [ ]p;
}

结果:

0 1 2
p[0]=0,p[1]=2

2. 

#include
using namespace std;
void main()
{
	int i = 5, & n = i, & k = n;
	i = ++n - 2;
	cout << "i=" << i << endl;
}
i=4

三、编程题 

1.使用c++语言中的预定义的流类对象cin和cout,编程实现从键盘输入年和月,计算并输出该年的月份共有多少天。

#include
using namespace std;
int  main()
{
	int year, month, day, cnt;
	cin >> year >> month;
	if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
		cnt = 1;
	else cnt = 0;
	switch (month)
	{
	case 1:
	case 3:
	case 5:
	case 7:
	case 8:
	case 10:
	case 12: day = 31; break;
	case 4:
	case 6:
	case 9:
	case 11: day = 30; break;
	case 2: day = 28 + cnt; break;
	}
	cout << "该年该月有" << day << "天";
	return 0;
}

2.用函数重载分别实现整型、长整型、双精度型数据的三次方的计算。

#include
using namespace std;
int zhengxing(int n)
{
	return n * n * n;
}
long  changzhengxing(long long n)
{
	return n * n * n;
}
double shuangjingdu(double n)
{
	return n * n * n;
}

int main()
{
	int i; long long j; double k;
	cin >> i >> j >> k;
	cout << zhengxing(i) << " " << changzhengxing(j) << " " << shuangjingdu(k) << endl;
	return 0;
}

第三章 

1.为什么要引入构造函数和析构函数?

构造函数的作用:初始化对象的成员变量

析构函数的作用:析构函数往往用来做“清理善后” 的工作(例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)

2.类的公有、私有和保护成员之间的区别是什么?

1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用。
3、protected:protected对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected就变成private。互为友好关系的类。

3.什么是拷贝构造函数,它何时被调用?

拷贝构造函数就是复制构造函数

调用时间:

(1)当用类的一个对象去初始化该类的另一个对象时,系统会自动调用拷贝构造函数;

(2)将一个对象作为实参传递给一个非引用类型的形参,系统会自动调用拷贝构造函数;

(3)从一个返回类为非引用的函数返回一个对象时,系统会自动调用拷贝构造函数;

(4)用花括号列表初始化一个数组的元素时,系统会自动调用拷贝构造函数。

4.设计一个计数器类,当建立该类的对象时其初始状态为0,考虑为计数器定义哪些成员?

数据成员,盛装两个运算量,还有字符成员,盛装运算符

5.定义一个时间类,能够提供和设置由时分秒组成的时间并编写出应用程序、定义时间对象、设置时间、输出该对象提供的时间。

#include
using namespace std;
class time
{
	private:
		int H;
		int M;
		int S;
	public:
		bool setTime(int ,int ,int );
		void print();
		bool isValid(int ,int ,int );
};
bool time:: setTime(int h,int m,int s)
{
	if(isValid(h,m,s))
	{
		H=h,M=m,S=s;
		return true;
	}
	else 
	return false;
}
void time:: print()
{
	cout<24||h<1||m>60||m<1||s>60||s<1) return false;
	else
	return true;
}
int main()
{
	time t;
	int h,m,s;
	cin>>h>>m>>s;
	while(!t.setTime(h,m,s))
	{
		cout<<"data error please input again:";
		cin>>h>>m>>s;
	}
	t.print();
	return 0;
 } 

6.设计一个学生类,它具有的私有数据成员是:注册号、姓名、数学、英语、计算机成绩;具有的公有成员函数是:求三门课总成绩的函数sum;求三门课平均成绩的函数average;显示学生数据信息的函数print;获取学生注册号的函数get_reg_num;设置学生数据信息的函数set_stu_inf。 

#include
#include
using namespace std;

class CStudent
{
private:
	int id;
	string name;
	int math;
	int english;
	static int count;
	static int mathc;
	static int englishc;
public:
	void setms()
	{

		cout << "name id math english" << endl;
		cin >> name >> id >> math >> english;
		count++;
		mathc = mathc + math;
		englishc = englishc + english;
	}
	int add()
	{
		return math + english;
	}
	void outms()
	{
		cout << "id"< S[i + 1].add())
			{
				*p = S[i];
				S[i] = S[i + 1];
				S[i + 1] = *p;
			}
		}
	}
	for (i = 9; i > 7; i--)
	{
		
		S[i].outms();
	}
	delete p;

	return 0;
}

 

7.模拟栈模型的操作,考虑顺序栈和链栈两种形式

//顺序栈
#include
#include
using namespace std;
#define Maxsize 100
typedef int DataType;
 
struct SeqStack{
	//int MAXNUM;
	int t;
	DataType *s;
};
 
typedef struct SeqStack *PSeqStack;
 
PSeqStack createEmptyStack_seq(int m)
{
	PSeqStack pastack  = (PSeqStack)malloc(sizeof(struct SeqStack));
	if(pastack!=NULL)
	{
		pastack->s = (DataType *)malloc(sizeof(DataType)*m);
		if(pastack->t ){
			//pastack->MAXNUM = m;
			pastack->t = -1;
			return pastack;
		}
		else free(pastack);
	}
	printf("Out of space!!\n");
	return NULL;
}
 
int isEmptyStack_seq(PSeqStack pastack){
	return(pastack->t == -1);
}
 
void push_seq(PSeqStack pastack,DataType x)
{
	if(pastack->t>=Maxsize -1)
		printf("Overflow!\n");
	else
	{
		pastack->t  = pastack->t+1;
		pastack->s[pastack->t ] = x;
	}
}
 
void pop_seq(PSeqStack pastack)
{
	if(pastack->t == -1)
	{
		printf("Underflow!\n");
	}
	else
		pastack->t = pastack->t-1;
}
 
DataType top_seq(PSeqStack pastack)
{
	if(pastack->t == -1)
	{
		printf("It is empty!\n");
	}
	else
		return (pastack->s[pastack->t]);
}
 
int main()
{
	PSeqStack pastack = createEmptyStack_seq(5);
	int flage = isEmptyStack_seq(pastack);
	push_seq(pastack,1);
	push_seq(pastack,3);
	push_seq(pastack,5);
	push_seq(pastack,9);
	pop_seq(pastack);
	printf("%d",top_seq(pastack));
	return 0;
	
}







//链栈
#include
#include
 
struct Node;
typedef struct Node *PNode;
typedef int DataType;
struct Node{
	DataType info;
	PNode link;
};
 
struct LinkStack{
	PNode top;
};
typedef struct LinkStack *PLinkStack;
 
PLinkStack createEmptyStack_link(void)
{
	PLinkStack plstack;
	plstack = (PLinkStack)malloc(sizeof(struct LinkStack));
	if(plstack!=NULL)
		plstack->top = NULL;
	else
		printf("Out of space!\n");
	return plstack;
}
 
int isEmptyStack_link(PLinkStack plstack)
{
	return (plstack->top ==NULL);
}
 
void push_link(PLinkStack plstack,DataType x)
{
	PNode p;
	p = (PNode)malloc(sizeof(struct Node));
	if(p==NULL)
	{
		printf("Out of space!\n");
	}
	else
	{
		p->info = x;
		p->link = plstack->top ;
		plstack->top = p; 
	}
}
 
void pop_link(PLinkStack plstack)
{
	PNode p;
	if(isEmptyStack_link(plstack))
		printf("Empty stack pop.\n");
	else
	{
		p = plstack->top;
		plstack->top = plstack->top->link ;
		free(p); 
	}
}
 
DataType top_link(PLinkStack plstack)
{
	if(plstack->top == NULL)
	{
		printf("Stack is empty!\n");
	}
	else
		return (plstack->top ->info);
}
 
int main()
{
	PLinkStack plstack = createEmptyStack_link();
	int flag = isEmptyStack_link(plstack);
	push_link(plstack,3);
	push_link(plstack,5);
	push_link(plstack,6);
	push_link(plstack,10);
	
	pop_link(plstack);
	printf("%d",top_link(plstack));
	
	return 0;
}

8.分析下列程序,写出其运行时的输出结果。 

​
​
_dh  
#include
using namespace std;
class date
{
public:
	date(int, int, int);
	date(int, int);
	date(int);
	date();
	void display();
private:
	int month;
	int day;
	int year;
};
date::date(int m, int d, int y) :month(m), day(d),year(y){}
date::date(int m, int d) :month(m), day(d) { year = 2005; }
date::date(int m) : month(m) { day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
void date::display()
{
	cout << month << " " << day << "/" << year << endl;
}
int main()
{
	date d1(10, 13, 2005);
	date d2(12, 30);
	date d3(10);
	date d4;
	d1.display();
	d2.display();
	d3.display();
	d4.display();
	return 0;
}

​

​

结果同14 

9.分析下面程序运行结果。

#include
using namespace std;
int main()
{
	cout<<"this "<<"is ";
	cout<<"a "<<"c++ ";
	cout<<"program. "<

输出:this is a c++ program.

10.分析下面程序运行结果。

#include
using namespace std;
int main()
{
	int a,b,c;
	a=10;
	b=23;
	c=a+b;
	cout<<"a+b=";
	cout<

输出结果为:a+b=33 

11.下列程序是否有错误。

#include
using namespace std;
int main()
{
	int a,b;
	c=a+b;
	cout>>"a+b=">>a+b;
}

有错误,c未声明且cout后面的符号方向反了。 

12.正确程序。

#include
using namespace std;
int main()
{
	int a,b,c;
	int add(int,int);
	cin>>a>>b;
	c=add(a,b);
	cout<<"a+b="<

13.程序作用:输入三个整数,将它们按照从小到大的顺序进行排列并输出。

 

#include
using namespace std;
int main()
{
	int a,b,c,temp;
	cin>>a>>b>>c;
	if(a>b)
	{
		temp=a;
		a=b;
		b=temp;
	}
	if(a>c)
	{
		temp=a;
		a=c;
		c=temp;
	}
	if(b>c)
	{
		temp=b;
		b=c;
		c=temp;
	}
	cout<

14. 分析下面的程序,写出其运行时的输出结果。

​
_dh  
#include
using namespace std;
class date
{
public:
	date(int, int, int);
	date(int, int);
	date(int);
	date();
	void display();
private:
	int month;
	int day;
	int year;
};
date::date(int m, int d, int y) :month(m), day(d),year(y){}
date::date(int m, int d) :month(m), day(d) { year = 2005; }
date::date(int m) : month(m) { day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
date::date() { month = 1; day = 1; year = 2005; }
void date::display()
{
	cout << month << " " << day << "/" << year << endl;
}
int main()
{
	date d1(10, 13, 2005);
	date d2(12, 30);
	date d3(10);
	date d4;
	d1.display();
	d2.display();
	d3.display();
	d4.display();
	return 0;
}

​

 C++课后习题答案_第1张图片

15.建立一个对象数组,内放5个学生的数据(学号,成绩),用指针指向数组首元素,输出第1,3,5个学生的数据。

#include 
using namespace std;
class Student
{
	public:
        Student(int num,double score)
        {
            this -> num = num;
            this ->score = score;
        }
        Student()
        {
            num = 0;
            score = 0;
        }
        void display();
	private:
        int num;
        double score;
};
void Student:: display()
{
	cout << num << " : " << score << endl;
}
int main()
{
	Student stu[5] = {Student(1001,80),Student(1002,85)
	,Student(1003,90),Student(1004,95),Student(1005,100)};
	Student *p = stu;
	for(p = stu; p < stu + 5; p += 2)
	{
		p -> display();
	}
	return 0;
 
}

16.阅读下面程序,分析其执行过程,写出输出结果。

#include
using namespace std;
class student
{
	public:
		student(int n,float s):num(n),score(s){
				}
		void change(int n,float s)
		{
			num=s;
			score=s;
		}
		void display()
		{
			cout<

C++课后习题答案_第2张图片

17.在time类声明为date的友元类,通过time类中的display函数引用date类对象的私有数据,输出年月日和时分秒。

#include 
using namespace std;

class Date;

class Time
{
    public:
        Time(int, int, int);
        void display(Date&);
    private:
        int hour;
        int minute;
        int sec;
};

class Date
{
    public:
        friend Time;
 
        Date(int, int, int);
    private:
        int month;
        int day;
        int year;
};
Time::Time(int hour, int minute, int sec)
{
    this->hour = hour;
    this->minute = minute;
    this->sec = sec;
}
void Time::display(Date& d)
{
    cout << d.month << "/" << d.day << "/" << d.year << endl;
    cout << hour << ":" << minute << ":" << sec << endl;
}

Date::Date(int month, int day, int year)
{
    this->month = month;
    this->day = day;
    this->year = year;
}

int main()
{
    Time t1(10, 13, 56);
    Date d1(12, 25, 2004);
    t1.display(d1);
    return 0;
}

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

你可能感兴趣的:(c++,开发语言)