(C++ Primer Plus课后编程练习第8章参考代码)
声明:
作者入门小白,将学习过程中的代码做一些分享,仅供大家参考,欢迎大家交流指正。全部编译运行过,水平有限,不喜勿喷。
环境:
Windows 10操作系统,Dev C++ 5.11,TDM-GCC 4.9.2 64-bit Release
1.编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而,如果提供了第二个参数(int类型),且参数不为0,则该函数打印字符串的次数将为该函数被调用的次数(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。是的,这是一个非常可笑的函数,但它让您能够使用本章介绍的一些技术。在一个简单的程序中使用该函数,以演示该函数是如何工作的。
代码:
#include <iostream>
using namespace std;
int count = 0; //统计函数被调用的次数
void print( const char * str ) //打印字符串函数
{
cout << str << endl;
}
void print( const char * str, int n ) //函数重载
{
count++; //每调用一次,count加1
for( int i=0; i<count; i++ ) //函数被累计调用多少次,就将字符串显示多少次
cout << str << "\t";
cout << endl;
}
int main()
{
print("abcd");
print("xyz", 2);
print("uvw", 5);
print("opq", 8);
return 0;
}
结果:
2.CandyBar结构包含3个成员。第一个成员存储candy bar的品牌名称;第二个成员存储candy bar的重量,即将CandyBar的引用、char指针、double和int作为参数,并用最后3个值设置相应的结构成员。最后3个参数的默认值分别为“Millennium Munch”、28.5和350.另外,该程序还包含一个以CandyBar的引用为参数,并显示结构内容的函数。请尽可能使用const。
代码:
#include <iostream>
#include <cstring> //使用strcpy函数需包含此头文件
using namespace std;
struct CandyBar
{
char name[20]; //品牌名称
float weight; //重量
int colories; //热量
};
//函数第一个参数为CandyBar对象的引用,三个参数均有默认值
void SetValue( struct CandyBar & cb, const char * str="Millennium Munch", const float we=2.85, const int clo=350 )
{
strcpy(cb.name, str); //修改名称
cb.weight = we; //修改重量
cb.colories = clo; //修改热量
cout << "finished" << endl;
}
void Show( const struct CandyBar & cb ) //显示结构内容的函数
{
cout << "name: " << cb.name << endl;
cout << "weight: " << cb.weight << endl;
cout << "colories: " << cb.colories << endl;
}
int main()
{
struct CandyBar ocb1={"Jack", 3.2, 5}; //创建结构体变量并初始化
SetValue(ocb1); //设置初值
Show(ocb1); //显示
SetValue(ocb1, "Bob", 3.5, 468); //设置特定值
Show(ocb1); //显示
return 0;
}
结果:
3.编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转换为大写,为此可以使用表6.4描述的函数toupper()。然后编写一个程序,它通过使用一个循环让您能够用不同的输入来测试这个函数,该程序的运行情况如下:
代码:
#include <iostream>
#include <cctype> //使用toupper函数需包含此头文件
#include <string>
using namespace std;
void Up( string & str ) //将字符串转换为大写
{
for( int i=0; str[i]; i++ )
{
str[i] = toupper(str[i]);
}
}
int main()
{
string s1;
cout << "Enter a string (q to quit): ";
//使用cin获取一个输入放在s1中,以换行符为结束标志
getline(cin, s1, '\n');
while( s1!="q" ) //输入q时退出
{
Up(s1);
cout << s1 << endl;
cout << "Next string (q to quit): ";
getline(cin, s1, '\n');
}
cout << "Bye." << endl;
return 0;
}
4.根据给出的程序框架,提供其中描述的函数和原型,从而完成该程序。注意,应有两个show()函数,每个都使用默认参数。请尽可能使用const参数。set()使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和实现类时使用的相似。(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器。)
代码:
#include <iostream>
#include <cstring>
using namespace std;
struct stringy
{
char * str; //指向字符串的指针
int ct; //字符串的长度
};
void set( struct stringy & osy, const char arr[] )
{
char * psy = new char[strlen(arr)+1]; //根据传入字符串的长度(包含'\0')申请空间
osy.str = psy; //osy.str指向新空间
strcpy(osy.str, arr); //将字符串拷贝到对应空间内
osy.ct = strlen(osy.str); //获取字符串长度
}
void show( const struct stringy & osy, const int n=1 )
{
for( int i=0; i<n; i++ )
cout << osy.str << endl;
}
void show( const char str[], const int n=1 )
{
for( int i=0; i<n; i++ )
cout << str << endl;
}
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set(beany, testing); //以testing的内容为beany做初始化
show(beany);
show(beany, 2); //显示beany的内容
testing[0] = 'D'; //修改testing中元素的值
testing[1] = 'u';
show(testing); //显示testing的内容
show(testing, 3);
show("Done!");
return 0;
}
结果:
5.编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素(由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。在一个程序中使用该函数,将T替换为一个包含5个int值的数组和一个包含5个double值的数组,以测试该函数。
代码:
#include <iostream>
using namespace std;
template <typename T> //函数模板
T max5( T arr[5] ) //返回值为 T,参数为包含5个 T类型元素的数组
{
T tmp = arr[0]; //将第一个元素作为最大值
for( int i=1; i<5; i++ ) //遍历剩余所有元素
{
if( arr[i]>tmp ) //tmp存储最大值
tmp = arr[i];
}
return tmp; //返回最大值
}
int main()
{
int a1[5] = {27, 6, 82, 15, 64};
double a2[5] = {15.2, 24.3, 8.07, 59.73, 3.14};
cout << "The max int: " << max5(a1) << endl;
cout << "The max double: " << max5(a2) << endl;
return 0;
}
结果:
6.编写函数模板maxn(),它将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包含4个double元素的数组来调用该函数。程序还包含一个具体化,它将char指针数组和数组中的指针数量作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串的地址。使用由5个字符串指针组成的数组来测试该具体化。
代码:
#include <iostream>
#include <cstring>
using namespace std;
template <typename T> //函数模板
T maxn( T arr[], int n ) //返回值为T类型,参数为T类型的数组、数组的元素个数
{
T tmp = arr[0];
for( int i=1; i<n ; i++ )
{
if( arr[i]>tmp )
tmp = arr[i];
}
return tmp; //返回最大值
}
template<> const char * maxn( const char * astr[], int n ) //const char*具体化
{
const char * pt = astr[0]; //默认第一个字符串最长
for( int i=1; i<n; i++ ) //遍历剩余其他字符串
{
if( strlen(astr[i])>strlen(pt) ) //pt指向长度最大的字符串
{
pt = astr[i];
}
else if( strlen(astr[i])==strlen(pt) ) //若两个字符串长度相同,
{
continue; //跳过该字符串,与下一个字符串对比
}
}
return pt; //返回最长字符串的地址
}
int main()
{
int a1[6] = {27, 6, 82, 15, 64, 53};
double a2[4] = {15.2, 24.3, 8.07, 59.73};
cout << "The max int: " << maxn(a1, 6) << endl; //测试 int maxn( int[], int );
cout << "The max double: " << maxn(a2, 4) << endl; //测试 double maxn( double[], int );
const char * strings[5] =
{
"Fight!", "Hello", "Bob", "Jack..", "Hello"
};
for( int i=0; i<(sizeof(strings)/sizeof(strings[0])); i++ ) //输出所有字符串
{
cout << strings[i] << endl;
}
cout << "The max string: " << maxn(strings, sizeof(strings)/sizeof(strings[0])) << endl;
return 0;
}
注意:sizeof(strings) / sizeof(strings[0]) = (sizeof(const char *)*5) / (sizeof(const char *)) = 5
结果:
7.修改程序清单8.14,使其使用两个名为SumArray()的模板函数来返回数组元素的总和,而不是显示数组的内容。程序应显示thing的总和以及所有debt的总和。
代码:
#include <iostream>
using namespace std;
template <typename T>
T SumArray( T arr[], int n ); //change
template <typename T>
T SumArray( T * arr[], int n ); //change
struct debts
{
char name[50];
double amount;
};
int main()
{
int things[6] = {13, 31, 103, 301, 310, 130};
struct debts mr_E[3] =
{
{"Ima Wolfe", 2400.0},
{"Ura Foxe", 1300.0},
{"Iby Stout", 1800.0}
};
double * pd[3];
for( int i=0; i<3; i++ )
pd[i] = &mr_E[i].amount;
cout << "Listing Mr.E's counts of things:\n";
cout << SumArray(things, 6) << endl; //显示thing的总和
cout << "Listing Mr.E's debts:\n";
cout << SumArray(pd, 3) << endl; //显示debt的总和
return 0;
}
template <typename T>
T SumArray( T arr[], int n ) //change
{
cout << "template A\n";
T total = 0;
for( int i=0; i<n; i++ )
total += arr[i]; //累加求和
return total;
}
template <typename T>
T SumArray( T * arr[], int n ) //change
{
cout << "template B\n";
T total = 0.0;
for( int i=0; i<n; i++ )
total += *arr[i]; //累加求和
return total;
}
结果: