C语言程序设计(郑莉)课后习题答案 下载本文

return *this; }

char & MyString::operator[](unsigned short offset) {

if (offset > itsLen)

return itsMyString[itsLen-1]; else

return itsMyString[offset]; }

char MyString::operator[](unsigned short offset) const {

if (offset > itsLen)

return itsMyString[itsLen-1]; else

return itsMyString[offset]; }

MyString MyString::operator+(const MyString& rhs) {

unsigned short totalLen = itsLen + rhs.GetLen(); MyString temp(totalLen);

for (unsigned short i = 0; i

for (unsigned short j = 0; j

void MyString::operator+=(const MyString& rhs) {

unsigned short rhsLen = rhs.GetLen(); unsigned short totalLen = itsLen + rhsLen; MyString temp(totalLen);

for (unsigned short i = 0; i

for (unsigned short j = 0; j

int main() {

MyString s1(\

cout << \

char * temp = \s1 = temp;

cout << \

char tempTwo[20];

strcpy(tempTwo,\s1 += tempTwo;

cout << \cout << \

cout << \s1[4]='x';

cout << \

cout << \

MyString s2(\MyString s3; s3 = s1+s2;

cout << \

MyString s4;

s4 = \

cout << \return 0; }

程序运行输出: S1: initial test S1: Hello World

tempTwo: ; nice to be here! S1: Hello World; nice to be here! S1[4]: o

S1: Hellx World; nice to be here! S1[999]: !

S3: Hellx World; nice to be here! Another myString S4: Why does this work?

6-26 编写一个3×3矩阵转置的函数,在main()函数中输入数据。 解:

#include

29

void move (int matrix[3][3]) {

int i, j, k; for(i=0; i<3; i++) for (j=0; j

k = matrix[i][j];

matrix[i][j] = matrix[j][i]; matrix[j][i] = k; } }

void main() {

int i, j; int data[3][3];

cout << \输入矩阵的元素\for(i=0; i<3; i++) for (j=0; j<3; j++) {

cout << \第\行第\<<\个元素为:\cin >> data[i][j]; }

cout << \输入的矩阵的为:\for(i=0; i<3; i++) {

for (j=0; j<3; j++) cout << data[i][j] << \cout << endl; }

move(data);

cout << \转置后的矩阵的为:\for(i=0; i<3; i++) {

for (j=0; j<3; j++) cout << data[i][j] << \cout << endl; } }

程序运行输出: 输入矩阵的元素 第1行第1个元素为:1 第1行第2个元素为:2 第1行第3个元素为:3 第2行第1个元素为:4 第2行第2个元素为:5

第2行第3个元素为:6 第3行第1个元素为:7 第3行第2个元素为:8 第3行第3个元素为:9 输入的矩阵的为: 1 2 3 4 5 6 7 8 9

转置后的矩阵的为: 1 4 7 2 5 8 3 6 9

6-27 编写一个矩阵转置的函数,矩阵的维数在程序中由用户输入。 解:

#include

void move (int *matrix ,int n) {

int i, j, k; for(i=0; i

k = *(matrix + i*n + j);

*(matrix + i*n + j) = *(matrix + j*n + i); *(matrix + j*n + i) = k; } }

void main() {

int n, i, j; int *p;

cout << \请输入矩阵的维数:\cin >> n;

p = new int[n*n];

cout << \输入矩阵的元素\for(i=0; i

cout << \第\行第\<<\个元素为:\cin >> p[i*n + j]; }

30

cout << \输入的矩阵的为:\for(i=0; i

for (j=0; j

move(p, n);

cout << \转置后的矩阵的为:\for(i=0; i

for (j=0; j

程序运行输出: 请输入矩阵的维数:3 输入矩阵的元素 第1行第1个元素为:1 第1行第2个元素为:2 第1行第3个元素为:3 第2行第1个元素为:4 第2行第2个元素为:5 第2行第3个元素为:6 第3行第1个元素为:7 第3行第2个元素为:8 第3行第3个元素为:9 输入的矩阵的为: 1 2 3 4 5 6 7 8 9

转置后的矩阵的为: 1 4 7 2 5 8 3 6 9

6-28 定义一个Employee类,其中包括表示姓名、街道地址、城市和邮编等属性,包括chage_name()和display()等函数;display()使用cout语句显示姓名、街道地址、城市和邮编等属性,函数change_name()改变对象的姓名属性,实现并测试这个类。 解: 源程序:

#include

#include

class Employee { private: char name[30]; char street[30]; char city[18]; char zip[6]; public:

Employee(char *n, char *str, char *ct, char *z); void change_name(char *n); void display(); };

Employee::Employee (char *n,char *str,char *ct, char *z) {

strcpy(name, n); strcpy(street, str); strcpy(city, ct); strcpy(zip, z); }

void Employee::change_name (char *n) {

strcpy(name, n); }

void Employee::display () {

cout << name << \cout << city << \}

void main(void) {

Employee e1(\张三\平安大街3号\北京\e1.display(); cout << endl;

e1.change_name(\李四\e1.display(); cout << endl; }

程序运行输出:

张三 平安大街3号 北京 100000 李四 平安大街3号 北京 100000

31

第 七 章 继承与派生

7-1 比较类的三种继承方式public公有继承、protected保护继承、private私有继承之间的差别。 解:

不同的继承方式,导致不同访问属性的基类成员在派生类中的访问属性也有所不同:

公有继承,使得基类public(公有)和protected(保护)成员的访问属性在派生类中不变,而基类private(私有)成员不可访问。

私有继承,使得基类public(公有)和protected(保护)成员都以private(私有)成员身份出现在派生类中,而基类private(私有)成员不可访问。

保护继承中,基类public(公有)和protected(保护)成员都以protected(保护)成员身份出现在派生类中,而基类private(私有)成员不可访问。

7-2 派生类构造函数执行的次序是怎样的? 解:

派生类构造函数执行的一般次序为:调用基类构造函数;调用成员对象的构造函数;派生类的构造函数体中的内容。

7-3 如果在派生类B已经重载了基类A的一个成员函数fn1(),没有重载成员函数fn2(),如何调用基类的成员函数fn1()、fn2()? 解:

调用方法为: A::fn1(); fn2();

7-4 什么叫做虚基类?有何作用? 解:

当某类的部分或全部直接基类是从另一个基类派生而来,这些直接基类中,从上一级基类继承来的成员就拥有相同的名称,派生类的对象的这些同名成员在内存中同时拥有多个拷贝,我们可以使用作用域分辨符来唯一标识并分别访问它们。我们也可以将直接基类的共同基类设置为虚基类,这时从不同的路径

继承过来的该类成员在内存中只拥有一个拷贝,这样就解决了同名成员的唯一标识问题。

虚基类的声明是在派生类的定义过程,其语法格式为: class 派生类名:virtual 继承方式 基类名

上述语句声明基类为派生类的虚基类,在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。声明了虚基类之后,虚基类的成员在进一步派生过程中,和派生类一起维护一个内存数据拷贝。

7-5 定义一个Shape基类,在此基础上派生出Rectangle和Circle,二者都有GetArea()函数计算对象的面积。使用Rectangle类创建一个派生类Square。 解: 源程序:

#include

class Shape { public: Shape(){} ~Shape(){}

virtual float GetArea() { return -1; } };

class Circle : public Shape { public:

Circle(float radius):itsRadius(radius){} ~Circle(){}

float GetArea() { return 3.14 * itsRadius * itsRadius; } private:

float itsRadius; };

class Rectangle : public Shape { public:

Rectangle(float len, float width): itsLength(len), itsWidth(width){}; ~Rectangle(){};

virtual float GetArea() { return itsLength * itsWidth; } virtual float GetLength() { return itsLength; } virtual float GetWidth() { return itsWidth; } private: float itsWidth;

32