第6章   数组、指针与字符串

6-20 实现一个名为 SimpleCircle 的简单圆类。其数据成员 int* itsRadius 为一个指向其半径值的指针,存放其半径值。设计对数据成员的各种操作,给出这个类的完整实现并测试这个类。

#include<iostream>
using namespace std;const float PI=3.14;
class SimpleCircle{private:int* itsRadius;public:SimpleCircle(){itsRadius = new int(5); }SimpleCircle(int R){itsRadius = new int(R);}SimpleCircle(const SimpleCircle &rhs){int val = rhs.getRadius();itsRadius = new int(val);}~SimpleCircle() {}int getRadius() const{return *itsRadius;}float area(){return PI*(*itsRadius)*(*itsRadius);}};
int main()
{int R;cout<<"请输入s2圆的半径:";cin>>R;SimpleCircle s1,s2(R),s3(s2);cout<<"该圆s1的面积是:"<<s1.area()<<endl;cout<<"该圆s2的面积是:"<<s2.area()<<endl;cout<<"该圆s3的面积是:"<<s3.area()<<endl;return 0;
}

6-21 编写一个函数,统计一条英文句子中字母的个数,在主程序中实现输入输出。

#include<iostream>
#include<string>
using namespace std;int count(char *s)
{int n;for(int i=0;s[i]!='\0';i++){if((s[i]>='A'&&s[i]<='Z')||(s[i]>='a'&&s[i]<='z'))n++;}return n;
}
int main()
{char s[100];cout<<"请输入一个英文句子:";gets(s);        //输入可以带空格的字符串 cout<<"这个句子中字母有"<<count(s)<<"个"<<endl; return 0;
}

6-22 编写函数 void reverse(string & s),用递归算法使字符串 s倒序。

#include <iostream>
#include <string>
using namespace std;string reverse(string& str)
{if(str.length()>1){string sub = str.substr(1,str.length()-2);return str.substr(str.length()-1,1) + reverse(sub) + str.substr(0,1);}else return str;
}
int main()
{string str;cout<<"请输入一个字符串:";cin>>str; cout<<"倒序反转后的字符串为:"<<reverse(str)<<endl;return 0;
}

6-23 设学生人数 N = 8,提示用户输入 N 个人的考试成绩,然后计算出他们的平均成绩并显示出来

#include <iostream>
using namespace std;int main()
{float num[8],score = 0,ave;cout<<"请输入8个人的考试成绩:"<<endl; for(int i=0;i<8;i++){cin>>num[i];score+=num[i];}ave=score/8;cout<<"它们的平均成绩为:"<<ave<<endl; return 0;
}

6-24 基于 char*设计一个字符串类 M yString,并且具有构造函数、析构函数、复制构造函数,重载运算符“+”,“=”,“+=”,“[]”,尽可能完善它,使之能满足各种需要(运算符重载功能为选做, 参见第 8 章)。

#include <iostream>
#include <cstring>
using namespace std;class myString{private:char *s;int Size;public:myString(){                      //无参数构造函数 s=new char[1];s[0]='\0';Size=0;}myString(char str[]){            //有参数构造函数 Size=strlen(str);s=new char[Size+1];strcpy(s,str);}myString( const myString &b ){   //复制构造函数 Size=strlen(b.s);s=new char[Size+1];strcpy(s,b.s);}~myString(){                     //析构函数 delete []s;Size=0;}int size(){                     //返回字符串长度 return Size;}int set(char str[]){           //拷贝字符串str Size=strlen(str);s=new char[Size+1];strcpy(s,str);return Size;}myString& operator= ( const myString &b ){    //重载运算符"=" Size=b.Size;s=new char[Size+1];strcpy(s,b.s);return *this;      //赋值运算,返回给自身this }myString operator+ ( const myString &b ){     //重载运算符"+" myString m;int l=Size+b.Size;m.s=new char[l+1];m.Size=l;strcat(s,b.s);strcpy(m.s,s);return m;       //返回一个新对象的字符串 }myString& operator+= ( const myString &b ){   //重载运算符"+=" myString m;int l=Size+b.Size;m.s=new char[l+1];m.Size=l;strcat(s,b.s);strcpy(m.s,s);*this=m;return *this;       //相加完的字符串返回给自身this}char &operator[] (int l){      //重载运算符"[]" return s[l];        //返回字符串 }myString sub( int start, int l ){  //返回一个 myString 对象m,其数据 s 为当前对象的 s[start, start + l] 范围内的字符 myString m;m.s=new char[l+1];m.Size=l;for(int i=0;i<l;i++)m.s[i]='\0';int j=0;for(int i=start-1;(i<start+l-1)&&(i<Size);i++,j++){m.s[j]=s[i];}return m;} void output(){           //输出字符串 cout<<s<<endl; }};int main()
{myString tmp;cout << tmp.size() << endl;  // 预期输出:0char t[20];                 //重载"[]" strcpy(t,"Hello");tmp += t;cout << t << endl;          // 预期输出:Hellochar s1[] = "abcd";myString a( s1 );a.output();                // 预期输出:abcdcout << a.size() << endl;  // 预期输出:4char s2[] = "1234";myString b( s2 );b.output();                // 预期输出:1234myString c;c = a;                     // 运算符"="重载 c.output();                // 预期输出:abcdcout << c.size() << endl;  // 预期输出:4c = a + b;                //运算符“+ ”重载 c.output();               // 预期输出:abcd1234cout << c.size() << endl;  // 预期输出:8myString d(c);             //复制构造函数 d.output();                // 预期输出:abcd1234d += c;                    //运算符“+= ”重载d.output();                //预期输出:abcd1234abcd1234b = c.sub( 3, 4 );b.output();               // 预期输出:cd12b = c.sub( 5, 10 );       // 从第5个位置至末尾,最多只有4个字符,故取完这4个字符即结束b.output();               // 预期输出:1234char s3[] = "6666666666";c.set( s3 );c.output();               // 预期输出10个6return 0;
}

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

#include <iostream>
#include <string>
using namespace std;int a[3][3];
void zhuanzhi(int a[3][3])
{for(int i=0;i<3;i++)for(int j=0;j<i;j++){int k=a[i][j];a[i][j]=a[j][i];a[j][i]=k;}
}
int main()
{cout<<"请输入一个3*3的矩阵:"<<endl;for(int i=0;i<3;i++)for(int j=0;j<3;j++)cin>>a[i][j];zhuanzhi(a);cout<<"转置后矩阵为:"<<endl;for(int i=0;i<3;i++){for(int j=0;j<3;j++)cout<<a[i][j]<<" ";cout<<endl;}return 0;
}

6-26 编写一个矩阵转置的函数,矩阵的行数和列数在程序中由用户输入。

#include<iostream>
using namespace std;void exchange(int *p1,int *p2,int r,int c)
{int i,j;cout<<"输入的矩阵为:"<<endl;              for(i=0;i<r;i++){for(j=0;j<c;j++)         cin>>p1[i*c+j];}for(i=0;i<c;i++)for(j=0;j<r;j++)p2[i*r+j]=p1[i+c*j];    //矩阵转置;这里的i j分别代表转置后的行列cout<<"转置后的矩阵为:"<<endl; for(i=0;i<c;i++){          //输出矩阵for(j=0;j<r;j++)cout<<p2[i*r+j]<<' ';cout<<endl;}
}
int main(){int r,c;cout<<"请输入矩阵行数、列数:"<<endl;cin>>r>>c;int *p3=new int[r*c];int *p4=new int[r*c];exchange(p3,p4,r,c);delete p3;delete p4;return 0;
}

6-27 定义一个 Employee 类,其中包括表示姓名、地址、城市和邮编等属性,包括setName()和display()等函数。display()使用cout语句显示姓名、地址、城市和邮编等属性,函数 setName()改变对象的姓名属性,实现并测试这个类。

#include <iostream>
#include <cstring>
using namespace std;class Employee
{
private:char name[50];char street[60];char city[60];char zip[80];
public:Employee(const char *n, const char *str, const char *ct, const char *z);void change_name(const char *n);void display();
};
Employee::Employee(const char *n, const char *str, const char *ct, const char *z)
{strcpy(name,n);strcpy(street,str);strcpy(city,ct);strcpy(zip,z);
}
void Employee::change_name(const char *n)
{strcpy(name,n);
}
void Employee::display()
{cout << name << " " << street << " "<< city << " " << zip;
}int main()
{Employee x("美国队长", "碧桂园2号楼", "地球", "34534534");x.display();cout << endl;x.change_name("钢铁侠");x.display();cout << endl;return 0;
}

其中,构造函数Employee和成员函数change_name()的形参都是使用指针来进行传递,类型const char *表示传入的形参为字符串常量,是无法改变的。对字符型的私有成员进行初始化赋值时,使用的是<cstring>头文件中的strcpy()函数。

此外,构造函数Employee的形参可以使用指针,也可以不使用。但使用指针可以提高程序的编译效率和执行速度,使程序更加简洁,也实现动态内存分配,减少内存的消耗。可以直接操纵内存地址,从而可以完成和汇编语言类似的工作。

6-28 分别将例6-10程序和例6-16程序中对指针的所有使用都改写为之等价的引用形式,比较修改前后的程序,体会在哪些情况下使用指针更好,哪些情况下使用引用更好。

//例6-10程序改写 #include<iostream>
using namespace std;void splitFloat(float x,int &intPart,float &fracPart)
{intPart = static_cast<int>(x);fracPart = x-intPart;
}int main()
{cout<<"Enter 3 float point numbers:"<<endl;for(int i=0;i<3;i++){float x,f;int n;cin>>x;splitFloat(x,n,f);cout<<"Integer Part="<<n<<" Fraction Part="<<f<<endl;}return 0;
}  
//例6-16程序改写 #include<iostream>
using namespace std;class Point{public:Point():x(0),y(0){cout<<"Default Constructor called."<<endl;} Point(int x,int y):x(x),y(y){cout<<"Constructor called."<<endl;}~Point(){ cout<<"Destructor called."<<endl;}int getX() const{ return x; }int getY() const{ return y; }void move(int newX,int newY){x=newX;y=newY;}private:int x,y;
}; int main()
{cout<<"Step one:"<<endl;Point &ptr1 = *new Point;delete &ptr1;cout<<"Step two:"<<endl;ptr1 = *new Point(1,2);delete &ptr1;return 0;
}

指针和引用的对比与分析:

  • 引用是一个别名,不能为NULL值,初始化指定被引用的对象后不能被重新分配了。引用本身(而非被引用的对象)的地址是不可以获得的,是被隐藏的。引用一经定义初始化后,对于它的全部行为,全是针对被引用对象的;
  • 指针是一个存放地址的变量。它可以被多次赋值,当需要的对变量重新赋以另外的地址或赋值为NULL时只能使用指针。
  1. 指针能进行动态内存分配和管理,减少内存的消耗。地址是变量的门牌号,指针传递大型数据的地址而不是传值,就像快捷方式一样可以省空间,省时间,提高了效率。
  2. 通过指针被调用函数可以向调用函数处返回除正常的返回值之外的其他数据,从而实现两者间的双向通信。
  3. 更容易实现函数的编写和调用。
  • 如果想要创建一些表示和实现各种复杂、大型的数据结构或者动态分配空间时,那么使用指针可以编写出更加高质量的程序,更灵活地分配好空间,改善某些子程序的效率。
  • 但对于简单小型的数据双向传递、减少大对象的参数传递开销这两个用途来说,引用可以很好地代替指针,它不需要像指针那样需要在主调函数中用“&”操作符传递函数,在被调函数中用“*”操作符使来访问数据,用引用比指针更加简洁、安全。

哦,对了,别忘记……

本专栏为本人大二C++课程的习题作业和一些学习经验的分享,供大家参考学习。如有侵权请立即与我联系,我将及时处理。


参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉,董渊、C++语言程序设计 第五版 -清华大学出版社- 郑莉,董渊(学生用书)

编译环境:Visual Studio 2019、Dev-C++

欢迎关注我的微信公众号,分享一些有趣的知识:程序猿的茶水间

C++语言程序设计第五版 - 郑莉(第六章课后习题)相关推荐

  1. C++语言程序设计第五版 - 郑莉(第九章课后习题)

    第9章  群体类和群体数据的组织 9-1 编写程序提示用户输入一个班级中的学生人数 n,再依次提示用户输入 n 个人在课程 A 中的考试成绩,然后计算出平均成绩,显示出来.请使用本书第 9 章中的数组 ...

  2. C++语言程序设计第五版 - 郑莉(第二章课后习题)

    第2章  C++简单程序设计 2-25 编写一个完整的程序,实现功能:向用户提问"现在正在下雨吗?",提示用户输入Y 或N.若输入为Y,显示"现在正在下雨.": ...

  3. C++语言程序设计第五版 - 郑莉(第八章课后习题)

    第8章 多态性 8-4 请编写一个计数器 Counter类,对其重载运算符"+". #include <iostream> using namespace std;cl ...

  4. 第三章 函数 C++语言程序设计第五版 - 郑莉

    本专栏为C++学习笔记,参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉 B站视频:https://space.bilibili.com/702528832/video PPT与代码已 ...

  5. C++语言程序设计第五版 - 郑莉-绪论(一)

    本专栏为C++学习笔记,参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉 B站视频:https://space.bilibili.com/702528832/video PPT与代码已 ...

  6. C++语言程序设计第五版 - 郑莉(第四章课后习题)

    第4章  类与对象 4-9设计并测试一个名为rectangle的矩形类,其属性为矩形的左下角与右上角坐标,根据坐标能计算矩形的面积. #include <iostream> using n ...

  7. C++语言程序设计第五版 - 郑莉(第七章课后习题)

    第7章  继承与派生 7-5 定义一个基类 Shape,在此基础上派生出 Rectangle 和 Circle,二者都有 getArea()函数计算对象的面积.使用 Rectangle类创建一个派生类 ...

  8. C++语言程序设计第五版 - 郑莉(第五章课后习题)

    第5章  数据的共享与保护 5-7定义一个Cat类,拥有静态数据成员 numOfCats,记录Cat的个体数目:静态成员函数getNumOfCats(),读取numOfCats.设计程序测试这个类,体 ...

  9. C++语言程序设计第五版 - 郑莉(第十一章课后习题)

    第11章  流类库与输入输出 11-3 使用 I/O 流以文本方式建立一个文件 test1.txt,写入字符"已成功写入文件!",用其他字处理程序(例如 Windows 的记事本程 ...

最新文章

  1. 前端计划——面试题总结-CSS篇
  2. 收敛标准对迭代次数影响
  3. Android屏幕适配全攻略(最权威的官方适配指导)(转),共大家分享。
  4. 商女不知亡国恨,一天到晚敲代码
  5. py2neo match
  6. 人物-李彦宏:李彦宏
  7. IDEA如何查看JDK源码
  8. Pascal基础(四)-常用函数和标准库
  9. [精简]托福核心词汇20
  10. Google SketchUp Cookbook: (Chapter 1) Making Multiple Copies
  11. Java数据结构项目
  12. 微信小程序自动回复用户消息
  13. 介绍一款 微信客服平台系统
  14. linux-centos7解决视频无法看问题(安装Adobe flash player)
  15. 需要了解的常用Webpack插件配置-loader加载器
  16. 热烈祝贺|酒事有鲤盛装亮相2023中国(山东)精酿啤酒产业发展创新论坛暨展览会
  17. 狗狗最近不爱吃饭了,还好有办法应对
  18. 淘宝天猫京东拼多多苏宁抖音等平台关键词监控价格API接口(店铺商品价格监控API接口调用展示)
  19. 国内代码托管中心-码云、自建代码托管平台-GitLab
  20. ByteV打造3D海上风电监控平台 ——助力风电能源可持续发展

热门文章

  1. 信息搜集学习--在线工具学习
  2. XMind、Axure、Visio这三个软件产品经理需要掌握哪个?要掌握到什么程度?
  3. COM组件开发(四)——VC++调用COM组件的方法
  4. Mybatis实现分页功能
  5. linux查找文件命令有哪些
  6. Java基础(7)字符串
  7. NVIDIA CUDA Toolkit 各个版本安装方式
  8. IDEA 配置git 完成项目下载和提交
  9. 浪潮服务器NF5280m5 raid硬盘驱动 配置,raid和系统
  10. 如何有效实现软件的需求管理 - 2