《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; }