《C++primerplus》第10章练习题
1.定义一个类表示银行账户。数据成员包括姓名,账号和存款。成员函数可以执行初始化数据、显示数据和取款存款的功能。
//Bank.cpp
#include<iostream>
#include"BankAccount.h" int main()
{
CBankAccount my_bank_account; my_bank_account.info_input(); //提示用户输入信息并存储
my_bank_account.info_show(); //输出用户的信息
my_bank_account.transfer(); //进行一次转账
my_bank_account.info_show(); //再次输出信息 system("pause");
return 0;
}
//BankAccount.h
#ifndef _BANKACCOUNT_H_
#define _BANKACCOUNT_H_ #include<cstring>
const int len = 20; class CBankAccount
{
private:
char name[len];
char account[len];
long deposit; public:
void info_input(); //提示输入信息
void set_name(const char * n_temp); //存储姓名
void set_account(const char * a_temp); //存储账户
void set_deposit(long d_temp); //存储存款
void info_show(); //输出账户信息
void transfer(); //转账
}; #endif // !_BANKACCOUNT_H_
//BankAccount.cpp
#include<iostream>
#include"BankAccount.h" void CBankAccount::info_input()
{
//存储姓名
char name_str[len];
std::cout << "Your name: ";
std::cin.get(name_str,len);
set_name(name_str);
std::cin.get(); //存储账户
char account_str[len];
std::cout << "Your account: ";
std::cin.get(account_str, len);
set_account(account_str);
std::cin.get(); //存储存款
long depo;
std::cout << "Your deposit: $";
std::cin >> depo;
set_deposit(depo);
} void CBankAccount::set_name(const char * n_temp)
{
strcpy_s(CBankAccount::name, n_temp);
} void CBankAccount::set_account(const char * a_temp)
{
strcpy_s(CBankAccount::account, a_temp);
} void CBankAccount::set_deposit(long d_temp)
{
CBankAccount::deposit = d_temp;
} void CBankAccount::info_show()
{
std::cout << "\nHere's your account info.\n";
std::cout << "Name: ";
for (int i = 0; CBankAccount::name[i] != '\0'; i++)
{
std::cout << name[i];
}
std::cout << "\n";
std::cout << "Account: " << CBankAccount::account << std::endl;
std::cout << "Deposit: $" << CBankAccount::deposit << std::endl;
} void CBankAccount::transfer()
{
int tmoney;
std::cout << "\n*Input (+ or -) number to transfer deposit: $";
std::cin >> tmoney;
CBankAccount::deposit += tmoney; //输入正数存钱,输入负数取钱
}
2.体验构造函数的重载。
定义一个存储个人姓名的类,创建两种构造函数,一种不带默认参数,一种带默认参数。主程序使用构造函数创建3个类,第一次什么参数也不给,第二次给一项参数,第三次参数都给定,各自使用成员函数输出姓名。
//Person.cpp
#include<iostream>
#include"ClassPerson.h" int main()
{
CPerson one;
CPerson two("Smythecraft");
CPerson three("Dimwiddy", "Sam");
one.Show();
std::cout << std::endl;
one.FormalShow();
std::cout << std::endl; //使用构造函数#1的输出
two.Show();
std::cout << std::endl;
two.FormalShow();
std::cout << std::endl; //使用构造函数#2的输出
three.Show();
std::cout << std::endl;
three.FormalShow(); system("pause");
return 0;
}
//ClassPerson.h
#ifndef _CLASSPERSON_H_
#define _CLASSPERSON_H_
#include<cstring> class CPerson
{
private:
static const int LIMIT = 25;
std::string m_lname;
char m_fname[LIMIT];
public:
CPerson() { m_lname = ""; m_fname[0] = '\0'; } //构造函数#1
CPerson(const std::string & ln, const char * fn = "Heyyou"); //构造函数#2,带默认参数
void Show();
void FormalShow();
}; #endif // !_CLASSPERSON_H_
//ClassPerson.cpp
#include<iostream>
#include"ClassPerson.h"
using namespace std; CPerson::CPerson(const string & ln, const char * fn ) //函数定义的参数就不用写出默认值了,否则编译会报参数重定义
{
m_lname = ln;
strcpy_s(m_fname, fn);
} void CPerson::Show()
{
for (int i = 0; m_fname[i] != '\0'; i++)
cout << m_fname[i];
cout << ",";
for (int i = 0; m_lname[i] != '\0'; i++)
cout << m_lname[i];
} void CPerson::FormalShow()
{
for (int i = 0; m_lname[i] != '\0'; i++)
cout << m_lname[i];
cout << ",";
for (int i = 0; m_fname[i] != '\0'; i++)
cout << m_fname[i];
}
3.(原题未使用)体验析构函数,练习this指针。
定义一个人员的类,存储姓名和年龄。构造函数提供交互,提示用户输入姓名和年龄,并使用this指针调用内部成员函数来存储信息。成员函数有设置姓名和年龄,获取姓名和年龄,以及一个比较年龄。比较年龄的成员函数接受从另一个类的成员函数获取的年龄,返回布尔值。最后输出比较结果。
//Person.cpp
#include <iostream>
#include"ClassPerson.h"
using namespace std; int main()
{
CPerson p1, p2;
if (p1.compare(p2))
{
cout << p1.get_name() << " is older than " << p2.get_name();
}
else if(p1.get_age() == p2.get_age())
{
cout << p1.get_name() << "is as old as " << p2.get_name();
}
else
{
cout << p1.get_name() << " is younger than " << p2.get_name();
} system("pause");
return 0;
}
#ifndef _CLASSPERSON_H_
#define _CLASSPERSON_H_
#include<cstring>
using namespace std; class CPerson
{
private:
char m_name[20] = {};
unsigned m_age = 0; public:
CPerson()
{
cout << "New person constructed.\n";
char n_tmp[20];
unsigned a_tmp;
cout << "Enter the name: ";
cin.get(n_tmp, 20);
this->set_name(n_tmp);
cout << "Enter the age: ";
cin >> a_tmp;
cin.get();
this->set_age(a_tmp);
}
~CPerson()
{
cout << "done.";
}
void set_name(const char * name_i)
{
strcpy_s(m_name, name_i);
}
const char * get_name()
{
return m_name;
}
void set_age(unsigned age_i)
{
m_age = age_i;
}
unsigned get_age()
{
return m_age;
}
bool compare(CPerson other_person)
{
return this->m_age > other_person.m_age;
}
}; #endif // !_CLASSPERSON_H_
4.(原题未使用)使用stack类,体验标准库函数memset()。
自定义一个字符类型的栈stack<char>,输入字符串,将字符压入栈。使用memset先将另一个字符串str2清空,再利用栈的后进先出特性,将前面输入的字符串倒序赋给str2,然后输出。
#include<iostream>
#include<stack>
using namespace std; int main()
{
stack<char>my_stack; char str1[20],str2[20];
cin.get(str1, 20); for (int x = 0; str1[x]!='\0'; x++)
{
my_stack.push(str1[x]);
}
memset(str2, '\0', sizeof(str2)); //将str2预设为空
//弹出栈,倒序赋给str2
for (int y = 0; !my_stack.empty(); y++)
{
str2[y] = my_stack.top();
my_stack.pop();
}
//输出字符串str2
for (int z = 0; str2[z] != '\0'; z++)
{
cout << str2[z];
} system("pause");
return 0;
}
*memset()第一项参数填字符串名,第二项填指定的字符,第三项填长度,可以填充整个字符串。
5.(对应第6题)完善书上的例程,提供一个用于表示移动的类的成员函数定义,并测试。
//Move.cpp
#include<iostream>
#include"CMove.h" int main()
{
Move walk; //目前的移动位置
Move run(1, 1); //下一步的移动位置 walk.showmove(); //显示当前位置
walk.add(run); //移动到(1,1)
walk.showmove(); //显示当前位置
run.reset(-1, 0); //重设移动路径(往负x方向移动一个单位)
walk.add(run); //按设定的路径移动
walk.showmove(); //显示当前位置
walk.reset(); //重设目前的位置(默认原点)
walk.showmove(); //显示当前位置 system("pause");
return 0;
}
//CMove.h
#include<iostream>
using namespace std; class Move
{
private:
double x;
double y; public:
Move(double a = 0, double b = 0);
void showmove();
Move add(const Move & m);
void reset(double a = 0, double b = 0);
}; Move::Move(double a, double b)
{
this->x = a;
this->y = b;
} void Move::showmove()
{
cout << "x: " << this->x << ",y: " << this->y << endl;
} Move Move::add(const Move & m)
{
this->x += m.x;
this->y += m.y;
return *this; //返回改动后的对象
} void Move::reset(double a, double b)
{
this->x = a;
this->y = b;
}
6.(原题未使用)练习类定义和this指针调用自己。
定义一个Enemy类,存储敌人的名字,等级,力量值和血量等属性。
构造函数会定义其属性,名字默认“哥布林”,默认等级1,力量10,血量10。成员函数有设定(修改)其属性和展示其属性的功能。析构函数输出一句提示。
其中,设定等级会决定其它的属性。等级越高,力量值和血量也会越高。力量值和血量会随等级按一定比例成长,10级以下,10-15级,15-20级都对应不同的成长因子。满级为20,当设定等级超过20时输出提示,并重置为20级。
//Enemy.cpp
#include<iostream>
#include"CEnemy.h" int main()
{
cout << "// This program helps you set a level //\n";
cout<<"// for an enemy and check its properties. //\n";
cout << "// Input number 0 to quit. //\n\n"; Enemy n1;
int lv_input;
cout << "Set it's level:";
while (cin >> lv_input)
{
if (lv_input == 0)
{
break;
}
n1.set_level(lv_input);
n1.get_info();
cout << "Set it's level:";
} system("pause");
return 0;
}
//CEnemy.h
#include<iostream>
#include<string>
using namespace std; class Enemy
{
private:
char m_name[20];
unsigned m_level = 1;
unsigned m_power = 10;
unsigned m_hp = 10;
public:
Enemy(const char * en = {"Goblin"}, unsigned lv = 1)
{
cout << "New enemy created.\n";
this->set_name(en);
this->set_level(lv);
}
~Enemy()
{
cout << "Enemies have been deleted.\n";
}
void set_name(const char * en)
{
strcpy_s(this->m_name, en);
} void set_power(unsigned pw)
{
this->m_power = pw;
}
void set_hp(unsigned hp)
{
this->m_hp = hp;
}
void set_level(unsigned lv);
void get_info();
}; void Enemy::set_level(unsigned lv)
{
unsigned hp_t = 10, pw_t = 10;
double grow_hp, grow_pw; //成长因子
if (lv < 10)
{
grow_hp = 1.4;
grow_pw = 1.3;
this->m_level = lv; //设定等级
for (; lv - 1 > 0; lv--)
{
hp_t *= grow_hp;
pw_t *= grow_pw;
}
}
else if ((lv >= 10) && (lv < 15))
{
this->set_level(9); //先将其设为9级
hp_t = this->m_hp; //获取9级的hp
pw_t = this->m_power; //和power
grow_hp = 1.3;
grow_pw = 1.2;
this->m_level = lv;
for (; lv - 9 > 0; lv--) //在此基础上计算
{
hp_t *= grow_hp;
pw_t *= grow_pw;
}
}
else if ((lv >= 15) && (lv <= 20))
{
this->set_level(14); //同上
hp_t = this->m_hp;
pw_t = this->m_power;
grow_hp = 1.2;
grow_pw = 1.1;
this->m_level = lv;
for (; lv - 14 > 0; lv--)
{
hp_t *= grow_hp;
pw_t *= grow_pw;
}
}
else
{
cout << "It has reached it's top level 20.\n";
this->set_level(20); //设定20级以上就提示满级,并重置为20
hp_t = this->m_hp;
pw_t = this->m_power;
}
this->set_hp(hp_t);
this->set_power(pw_t);
} void Enemy::get_info()
{
cout << "Here's the enemy's properties:\n";
cout << "[Name]" << m_name << " [Level]" << m_level << " [power]" << m_power;
cout << " [HP]" << m_hp;
cout << endl;
}
《C++primerplus》第10章练习题的更多相关文章
- 《构建之法》之第8、9、10章读后感 ,以及sprint总结
第8章: 主要介绍了软件需求的类型.利益相关者,获取用户需求分析的常用方法与步骤.竞争性需求分析的框架NABCD,四象限方法以及项目计划和估计的技术. 1.软件需求:人们为了解决现实社会和生活中的各种 ...
- 敏捷软件开发:原则、模式与实践——第10章 LSP:Liskov替换原则
第10章 LSP:Liskov替换原则 Liskov替换原则:子类型(subtype)必须能够替换掉它们的基类型(base type). 10.1 违反LSP的情形 10.1.1 简单例子 对L ...
- 孙鑫视频学习:对第10章设置线宽时为什么不调用UpDateData(TRUE)的理解
在第10章10.2.1小节中,首先分别对视图类和对话框类添加了一个名为m_nLineWidth的int型变量,再将用户在CSetting dlg对话框的edit控件中输入的线宽值记录在dlg.m_nL ...
- 第10章 系统级I/O
第10章 系统级I/O 10.1 Unix I/O 一个Unix文件就是一个m个字节的序列:B0,B1,…,BK,…,Bm-1 Unix I/O:一种将设备优雅地映射为文件的方式,允许Unix内核引出 ...
- 高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化
高性能Linux服务器 第10章 基于Linux服务器的性能分析与优化 作为一名Linux系统管理员,最主要的工作是优化系统配置,使应用在系统上以最优的状态运行.但硬件问题.软件问题.网络环境等 ...
- Linux就这个范儿 第10章 生死与共的兄弟
Linux就这个范儿 第10章 生死与共的兄弟 就说Linux系统的开机.必须经过加载BIOS.读取MBR.Boot Loader.加载内核.启动init进程并确定运行等级.执行初始化脚本.启动内核模 ...
- 【翻译】《深入解析windows操作系统第6版下册》第10章:内存管理
[翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第一部分) [翻译]<深入解析windows操作系统第6版下册>第10章:内存管理(第二部分) [翻译] ...
- 《构建之法》第8、9、10章读后感和Sprint总结
<构建之法>第8.9.10章读后感 第八章重点讲了需求分析,在一个项目中,需求分析是最基础也是最重要的,只有充分了解了用户需求,我们才不会走弯路,才能做出正确的规划,保证项目的进行是按照 ...
- JavaScript高级程序设计(第三版)学习笔记8、9、10章
第8章,BOM BOM的核心对象是window,具有双重角色,既是js访问浏览器的一个接口,又是ECMAScript规定的Global对象.因此,在全局作用域中声明的函数.变量都会变成window对象 ...
随机推荐
- 基于Log4Net记录日志到SQLServer(自定义字段)
本文记录通过log4net将日志信息记录到SQLServer数据库中. 1.新建控制台应用程序 Log4NetDemo: 2.通过NuGet安装Log4Net (项目版本2.0.8): 3.项目根目录 ...
- 分数运算(gcd)
时间限制 1000 ms 内存限制 32768 KB 代码长度限制 100 KB 判断程序 Standard (来自 小小) 题目描述 计算机中采用浮点数表示所有实数,但这意味着精度丢失.例如无法精确 ...
- C014:不用算术分割显示逆序三位数
程序: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { int handred,ten,ge; do{ pri ...
- 面试官问我:看过sharding-jdbc的源码吗?我吧啦吧啦说了一通!!
写在前面 在产品初期快速迭代的过程中,往往为了快速上线而占据市场,在后端开发的过程中往往不会过多的考虑分布式和微服务,往往会将后端服务做成一个单体应用,而数据库也是一样,最初会把所有的业务数据都放到一 ...
- axios post提交数据的三种请求方式
1.Content-Type: application/json import axios from 'axios' let data = {"code":"1234&q ...
- 【Flutter 实战】路由堆栈详解
老孟导读:Flutter中路由是非常重要的部分,任何一个应用程序都离不开路由管理,此文讲解路由相关方法的使用和路由堆栈的变化. Flutter 路由管理中有两个非常重要的概念: Route:路由是应用 ...
- springboot 配置和使用过滤器
首先在Application文件中添加注解@ServletComponentScan自动扫描当前类的同包以及子包,这样才能将filter装入bean package com.example.acade ...
- archaius(4) 属性对象
讲完上一节,我们就可以使用合理的配置管理器或者实现自己的配置管理来管理我们的配置项了.archaius还提供了一种新的配置使用的方式. 动态属性对象 动态属性对象针对每个配置项以对象方式进行操作,并且 ...
- java.lang.NoSuchMethodError: org.springframework.util.Assert.isTrue(ZLjava/util/function/Supplier;)V
spring-data-redis 2的版本只支持spring5和spring boot2+,建议降低spring-data-redis版本 <!-- redis --> <depe ...
- 7.Semaphore-信号量