C++ Primer Plus 第八章编程题练习
第一题
题目描述
编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而,如果提供了第二个参数 (int类型),且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。是的,这是一个非常可笑的函数,但它让您能够使用本章介绍的一些技术。在一个简单的程序中使用该函数,以演示该函数是如何工作的。
代码片段
#include<iostream>
using namespace std;
int count=0;
void printstr(char *,int n=0);
int main(void)
{
cout<<"please enter a string less than 20 chars(empty line to quit): ";
char name[21];
while(1)
{
cin.getline(name,21);
if(!name[0])
break;
cout<<"Do you have the second parameter? y/n?: ";
char ch;(cin>>ch).get();
if(ch=='n')
printstr(name);
else
{
int num;
cout<<"Please enter the number: ";
(cin>>num).get();
printstr(name,num);
}
count++;
cout<<"The next string input: ";
}
cout<<"Bye!";
while(cin.get()!=EOF);
return 0;
}
void printstr(char *s,int n)
{
if(n==0)
cout<<s<<endl;
else
{
for(int i=0;i<count;i++)
cout<<s<<endl;
}
return;
}
/* 编写通常接受一个参数(字符串的地址),并打印该字符串的函数。然而,如果提供了第二个参数
(int类型),且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数
(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。
是的,这是一个非常可笑的函数,但它让您能够使用本章介绍的一些技术。
在一个简单的程序中使用该函数,以演示该函数是如何工作的。 */
第二题
题目描述
CandyBar结构包含3个成员。第一个成员存储candybar的品牌名称,第二个成员存储candybar 的重量(可能有小数),第三个成员存储candybar的热量(整数)。请编写yi个程序,它使用一个这样的函 数,即将CandyBar的引用,char指针、double和int作为参数,并用最后3个值设置相应的结构成员最 后3个参数的默认值分别为“MileniumMunch"、2.85和350。另外,该程序还包含一个以CandyBar的 引用为参数,并显示结构内容的函数。请尽可能使用const
代码片段
#include<iostream>
using namespace std;
typedef struct{
string brand;
double weight;
int heat;
}TT;
void settt(TT&,const string a="Milenium Munch",const double b=2.85,const int c=350);
void printtt(const TT&);
int main(void)
{
TT s[11];
settt(s[0]);
string a;
double b;
int c;
cout<<"Please use the format below to enter your data: "<<endl;
printtt(s[0]);
cout<<"You can enter no more than 10 groups data!(empty line to quit)\n";
int i;
for(i=1;i<=10;i++)
{
cout<<'#'<<i<<" (Remaining amount: "<<10-i<<")\n";
cout<<"Brand: ";getline(cin,a);
if(a=="")
break;
cout<<"Weight: ";(cin>>b).get();
cout<<"Heat: ";(cin>>c).get();
cout<<endl;
settt(s[i],a,b,c);
}
cout<<"The enter has finished!\nBelow are the all data: \n";
for(int j=1;j<=i-1;j++)
{
cout<<'#'<<j<<endl;
printtt(s[j]);
}
cout<<"Data have been outputted!\n";
while(cin.get()!=EOF);
return 0;
}
void settt(TT& s,const string a,const double b,const int c)
{
s.brand=a;
s.heat=c;
s.weight=b;
return;
}
void printtt(const TT& a)
{
cout<<"Brand: "<<a.brand<<endl;
cout<<"Weight: "<<a.weight<<endl;
cout<<"Heat: "<<a.heat<<endl;
return ;
}
/* CandyBar结构包含3个成员。第一个成员存储candybar的品牌名称,第二个成员存储candybar
的重量(可能有小数),第三个成员存储candybar的热量(整数)。请编写yi个程序,它使用一个这样的函
数,即将CandyBar的引用,char指针、double和int作为参数,并用最后3个值设置相应的结构成员最
后3个参数的默认值分别为"MileniumMunch"、2.85和350。另外,该程序还包含一个以CandyBar的
引用为参数,并显示结构内容的函数。请尽可能使用const */
第三题
题目描述
编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转换为大写,为此可使用表6.4描述的函数toupper()。然后编写一个程序, 它通过使用一个循环让您能够用不同的输入 来测试这个函数,该程序的运行情况如下:
Enter a string (q to quit): go away
GO AWAY
Next string (q to quit): good grief!
GOOD GRIEF !
Next string (q to quit): q
Bye.
代码片段
#include<iostream>
#include<cctype>
using namespace std;
void conver(string&);
inline void showstr(const string);
int main(void)
{
cout<<"Enter a string (q to quit): ";
string a;
while(1)
{
getline(cin,a);
if(a[0]=='q')
break;
conver(a);
showstr(a);
cout<<"Next string (q to quit): ";
cin.clear();
cin.sync();
}
cout<<"Bye!\n";
while(cin.get()!=EOF);
return 0;
}
void conver(string &a)
{
for(int i=0;a[i];i++)
a[i]=toupper(a[i]);
return;
}
inline void showstr(const string a)
{
cout<<a<<endl;
}
/* 编写一个函数,它接受一个指向string对象的引用作为参数,
并将该string对象的内容转换为大写,为此可使用表6.4描述的函数toupper()。
然后编写一个程序, 它通过使用一个循环让您能够用不同的输入
来测试这个函数,该程序的运行情况如下:
Enter a string (q to quit): go away
GO AWAY
Next string (q to quit): good grief!
GOOD GRIEF !
Next string (q to quit): q
Bye. */
第四题
题目描述
下面是一个程序框架,请提供其中描述的函数和原型,从而完成该程序。注意,应有两个show( )函数,每个都使用默认参数。 请尽可能使用cosnt参数。set( )使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和 实现类时使用的相似。(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器。)
#include <iostream>
#include <cstring>// for strlen(),strcpy()
using namespace std;
struct stringy {
char *str;// points to a string
int ct;// length of string (not counting '\0')
};// prototypes for set(), show(), and show() go here
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set (beany,testing);
// first argument is a reference ,
// allocates space to hold copy of testing,
// sets str member of beany to point to the
// new block, copies testing to new block,
// and sets ct member of beany
show (beany);
// prints member string once
show (beany, 2); // prints member string twice
testing[0] = 'D';
testing[1] = 'u';
show (testing); // prints testing string once
show(testing,3); // prints testing string thrice
show ( "Done!");
return 0;
}
代码片段
#include <iostream>
#include <cstring>// for strlen(),strcpy()
using namespace std;
struct stringy {
char *str;// points to a string
int ct;// length of string (not counting '\0')
};// prototypes for set(), show(), and show() go here
void set(stringy& a,const char *b)
{
a.ct=strlen(b);
a.str=new char[a.ct+1];
strcpy(a.str,b);
}
void show(const stringy a,int n=1)
{
for(int i=0;i<n;i++)
cout<<a.str<<endl;
}
void show(const char *a,int n=1)
{
for(int i=0;i<n;i++)
cout<<a<<endl;
}
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set (beany,testing);
// first argument is a reference ,
// allocates space to hold copy of testing,
// sets str member of beany to point to the
// new block, copies testing to new block,
// and sets ct member of beany
show (beany);
// prints member string once
show (beany, 2); // prints member string twice
testing[0] = 'D';
testing[1] = 'u';
show (testing); // prints testing string once
show(testing,3); // prints testing string thrice
show ( "Done!");
while(cin.get()!=EOF);
return 0;
}
第五题
题目描述
编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素 (由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。在一个程序中使用该函数,将 T替换为一个包含5个int值的数组和一个包含5个dowble值的数组,以测试该函数。
代码片段
#include <iostream>
using namespace std;
template <class T>
T max5(T *a)
{
T max=a[0];
for(int i=1;i<5;i++)
if(max<a[i])
max=a[i];
return max;
}
int main()
{
int testint[5]={1,2,5,4,2};
double testdouble[5]={1.85469,7.569851,5.321456,9,15.23654789};
int result=max5(testint);
cout<<result<<endl;
double result1=max5(testdouble);
cout<<fixed;
cout<<result1<<endl;
while(cin.get()!=EOF);
return 0;
}
/* 编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素
(由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。在一个程序中使用该函数,将
T替换为一个包含5个int值的数组和一个包含5个dowble值的数组,以测试该函数。 */
第六题
题目描述
编写模板函数maxn(),它将由一个 T类型元素组成的数组和一个表示数组元素数目的整数作为参 数,并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包 含4个double元素的数组来调用该函数。程序还包含一个 具体化,它将char指针数组和数组中的指针数量 作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串的地址。使 用由5个字符串指针组成的数组来测试该具体化。
代码片段
#include <iostream>
#include<cstring>
using namespace std;
template <class T>
T maxn(T *a,int n)
{
T max=a[0];
for(int i=1;i<n;i++)
if(max<a[i])
max=a[i];
return max;
}
template<> char* maxn<char *>(char **a,int n)
{
int m=strlen(a[n-1]);
char* ps=a[n-1];
for(int i=n-2;i>=0;i--)
if(strlen(a[i])>=m)
{
m=strlen(a[i]);
ps=a[i];
}
return ps;
}
int main()
{
int a[6]={5,8,4,6,3,9};
double b[4]={1.854,2.369,7.8584,6.5126};
char *s1="123456";
char *s2="123";
char *s3="123456789";
char *s4="987654321";
char *s5="";
char *c[5]={s1,s2,s3,s4,s5};
cout<<fixed;
cout<<maxn(a,6)<<endl<<maxn(b,4)<<endl<<maxn(c,5)<<endl;
while(cin.get()!=EOF);
return 0;
}
/* 编写模板函数maxn(),它将由一个 T类型元素组成的数组和一个表示数组元素数目的整数作为参
数,并返回数组中最大的元素。在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包
含4个double元素的数组来调用该函数。程序还包含一个 具体化,它将char指针数组和数组中的指针数量
作为参数,并返回最长的字符串的地址。如果有多个这样的字符串,则返回其中第一个字符串的地址。使
用由5个字符串指针组成的数组来测试该具体化。 */
第七题
题目描述
修改程序清单8.14,使其使用两个名为SumArray()的模板函数来返回数组元素的总和,而不是显 示数组的内容。程序应显示thing的总和以及所有debt的总和。
代码片段
#include <iostream>
using namespace std;
struct debt{
char name[40];
double debts;
};
template <class T>
double SumArray(T* a[],int n);
template<class T>
T SumArray(T a[],int n);
int main()
{
int things[9]{1,2,3,4,5,6,7,8,9};
cout<<SumArray(things,9)<<endl;
debt ps[4]={"name1",1.1,"name2",2.2,"name3",3.3,"name4",3.3};
double *pt[4];
for(int i=0;i<4;i++)
pt[i]=&ps[i].debts;
cout<<SumArray(pt,4)<<endl;
while(cin.get()!=EOF);
return 0;
}
template <class T>
double SumArray(T* a[],int n)
{
double sum=0;
for(int i=0;i<n;i++)
sum+=*a[i];
return sum;
}
template<class T>
T SumArray(T a[],int n)
{
T sum=0;
for(int i=0;i<n;i++)
sum+=a[i];
return sum;
}
/* 修改程序清单8.14,使其使用两个名为SumArray()的模板函数来返回数组元素的总和,而不是显
示数组的内容。程序应显示thing的总和以及所有debt的总和。 */
这一题需要注意,不能在模板函数参数中添加const限定符,不然对于重载模板函数的匹配将匹配到第二个声明处;也可以只对第二个模板函数的声明添加const限定符,使得匹配顺序的确定更加明显。
关于为什么匹配会因为const出错,这确实是一个我还不知道为什么的问题😭
这个问题请看:问题链接