// 第八章.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>//预编译,使用iostream文件在编译前替代这行代码
#include <array>
#include <string>
#include <iomanip>
#include<typeinfo>
const int SIZE = 101;
static int flag = 0;
using namespace std;//将使用std命名空间中的定义
/* 编写一个通常接受一个参数(字符串的地址),并打印该字符串的函数。
然而,如果提供了第二个参数(int)类型,且该参数不为0,则该函数打印字符串的次数将为该函数被调用的次数。
(注意,字符串的打印次数不等于第二个参数的值,而等于函数被调用的次数)。
是的,这是一个非常可笑的函数(我怎么不觉得可笑,手动微笑),但它能让您使用本章介绍的一些技术。
在一个简单的程序中使用该函数,以演示该函数是如何工作的。
*/
void print(string str,int n=0);
void print(string str, int n)
{
flag++;
cout << "第" << flag << "次调用print函数:\n";
if (n!=0)
{
for (int i = 0; i < flag; i++)
{
cout <<str << endl;
}
}
else
cout << str << endl;
}
void Xiti1()//
{
string str;
int n=1;
while (n!=0)
{
cout << "输入字符串:";
cin.get();
getline(cin, str);
cout << "输入一个整数:";
if (cin >> n)
{
cout << "输入了字符和数字,执行双参数\n";
print(str, n);
}
else
{
cout << "仅输入字符,执行默认值\n";
print(str);
}
}
return;
}
/*. CandyBar结构包含3个成员。第一个成员存储candy bar的品牌名称;第二个成员存储candy bar的重量(有可能有小数);
第三个成员存储candy bar的热量。请编写一个程序,它使用一个这样的函数,即将CandyBar的引用、char指针、double和int作为参数,
并用最后3个值设置相应的结构成员。最后3个参数的默认值分别为"Millennium Munch"、2.85 和350。
另外,该程序还包含一个以CandyBar的引用为参数,并显示结构内容的函数。请尽可能使用const。
。*/
struct CandyBar
{
char pinpai[30];
double weight;
int reliang;
};
void setting(CandyBar &cb ,const char*pp="Millennium Munch",const double weight=2.85,const int reliang=350);
void setting(CandyBar &cb, const char*pp, const double weight,const int reliang)
{
strcpy_s(cb.pinpai, pp);
cb.reliang = reliang;
cb.weight = weight;
}
void display(const CandyBar &cb);
void display(const CandyBar &cb)
{
cout << "品牌为:" << cb.pinpai<<endl;
cout << "重量为:" << cb.weight << endl;
cout << "热量为:" << cb.reliang << endl;
}
void Xiti2()//
{
CandyBar cb;
char pinpai[30];
double weight;
int reliang;
setting(cb);
cout << "默认值\n";
display(cb);
cout << "输入品牌:\n";
cin.get();
cin.getline(pinpai, 30);
cout << "输入重量:";
cin >> weight;
cout << "输入热量:\n";
cin >> reliang;
setting(cb, pinpai, weight, reliang);
display(cb);
setting(cb);
cout << "默认值\n";
display(cb);
return;
}
/*编写一个函数,它接受一个指向string对象的引用作为参数,并将该string对象的内容转换为大写,
为此可使用cctype中的字符函数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.
*/
void toup(string & str);
void toup(string & str)
{
for (unsigned int i = 0; i < str.size(); i++)
{
str[i]=toupper(str[i]);
}
}
void Xiti3()//简述:
{
cout << "输入一个字符串:\n";
string str;
cin.get();
getline(cin, str);
while ('q'!=str[0])
{
toup(str);
cout << str<<endl;
cout << "来,下一个";
getline(cin, str);
}
cout << "bye!";
return;
}
/*.请提供其中描述的函数和原型,从而完成该程序。注意,应有两个show()函数,每一个都使用默认参数。
请尽可能使用const参数。set()使用new分配足够的空间来存储指定的字符串。这里使用的技术与设计和实现类时使用的相似。
(可能还必须修改头文件的名称,删除using编译指令,这取决于所用的编译器)
*/
struct stringy {
char * str; // points to a string
int ct; // length of string (not counting '\0')
};
void set(stringy & be,const char * str);
void set(stringy & be, const char * str)
{
be.str = new char[strlen(str) + 1];
strcpy_s(be.str, strlen(str)+1, str);
be.ct = strlen(str) + 1;
}
void show(stringy&be, int n=1);
void show(stringy&be, int n)
{
for (int i = 0; i < n; i++)
{
cout << be.str << endl;
}
cout << endl;
}
void show(char *str, int n=1);
void show(char *str, int n)
{
for (int i = 0; i < n; i++)
{
cout << str << endl;
}
cout << endl;
}
void Xiti4()//
{
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
//第一个参数是一个引用,分配空间来保存testing副本,
//设置beany的str成员指向新块,将testing复制到新块,
//并设置beany的ct成员
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;
}
/*. 编写模板函数max5(),它将一个包含5个T类型元素的数组作为参数,并返回数组中最大的元素
(由于长度固定,因此可以在循环中使用硬编码,而不必通过参数来传递)。
在一个程序中使用该函数,将T替换为一个包含5个int值的数组和一个包含5个double值的数组,以测试该函数
*/
template <typename T>
T max5(T * pp);
template <typename T>
T max5(T * pp)
{
T a = pp[0];
for (int i = 1; i < 5; i++)
{
if (a < pp[i]) a = pp[i];
}
return a;
}
void Xiti5()//
{
int arr[5] = { 1,2,3,4,5 };
double arr2[5] = { 1.1,2.2,3.3,4.4,5.5 };
cout << max5(arr);
cout << max5(arr2);
return;
}
/*编写模板函数maxn(),它将由一个T类型元素组成的数组和一个表示数组元素数目的整数作为参数,并返回数组中最大的元素。
在程序对它进行测试,该程序使用一个包含6个int元素的数组和一个包含4个double元素的数组来调用该函数。
程序还包含一个具体化,它将char指针数组和数组中指针数量作为参数,并返回最长的字符串的地址。
如果有多个这样的字符串,将返回其中第一个字符的地址。使用由5个字符串指针组成的数组来测试该具体化。
。*/
template<typename T>
T maxn(T *arr, int n);
template<typename T>
T maxn(T *arr,int n)
{
T a = arr[0];
for (int i = 1; i < n; i++)
{
if (a<arr[i]) a = arr[i];
}
return a;
}
template <> char*maxn(char * arr[], int n);
template <> char*maxn(char * arr[], int n)
{
char *a = arr[0];
for (int i = 1; i < n; i++)
{
if (strlen(a)<strlen(arr[i]))
{
a = arr[i];
}
}
return a;
}
void Xiti6()//简述:
{
int arr[6] = { 1,2,3,4,5,6 };
double arr1[4] = { 1.1,2.2,3.3,4.4 };
char *arr3[5] = { "asdf","sdghgj","sdfahg","agrgfjnfgj","sdfaew" };
char *arr4[5] = { "wtesgasdg","awerawegfa","werwagads","wr3gfd","wersdg" };
cout << maxn(arr, 6) << endl;
cout << maxn(arr1, 4) << endl;
cout << maxn(arr3, 5) << endl;
cout << maxn(arr4, 5) << endl;
return;
}
/*修改程序清单8.14 ,使其使用两个名为SumArray()的模板函数返回数组元素的总和。
而不是显示数组的内容。程序应显示thing的总和以及所有debt的总和。
*/
template <typename T> // template A
void SumArray(T arr[], int n);
template <typename T> // template B
void SumArray(T * arr[], int n);
struct debts
{
char name[50];
double amount;
};
template <typename T>
void SumArray(T arr[], int n)
{
using namespace std;
cout << "template A\n";
T sum = 0;
for (int i = 0; i < n; i++)
sum += arr[i];
cout << sum;
cout << endl;
}
template <typename T>
void SumArray(T * arr[], int n)
{
using namespace std;
cout << "template B\n";
T sum = 0;
for (int i = 0; i < n; i++)
sum += *arr[i];
cout << sum;
cout << endl;
}
void Xiti7()//
{
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];
// set pointers to the amount members of the structures in mr_E
for (int i = 0; i < 3; i++)
pd[i] = &mr_E[i].amount;
cout << "Listing Mr. E's counts of things:\n";
// things is an array of int
SumArray(things, 6);// uses template A
cout << "Listing Mr. E's debts:\n";
// pd is an array of pointers to double
SumArray(pd, 3);// uses template B (more specialized)
// cin.get();
return;
}
/* 在不使用array类的情况下完成程序7.15 所做的工作,编写这样的两个版本:
a. 使用 const char* 数组存储表示季度名称的字符串,并使用double数组存储开支。
b. 使用 const char*数组存储表示季度名称的字符串,并使用一个结构,该结构只有一个成员——一个用于存储开支的数组。
这种设计与使用array类的基本设计类似。
程序7.15 如下:
。
*/
void Xiti8()//
{
return;
}
/* 这个练习让您编写处理数组和结构的函数。
下面是程序框架,请提供其中描述的函数,以完成该程序。
。*/
// getinfo() has two arguements:a pointer to the first element of an array of student structures
// and an int representing the number of element of the array.
// getinfo()有两个参数:指向student结构数组的第一个元素的指针和一个表示数组元素个数的int。
// The function solicits and stores data about students.
// 该函数征求并存储有关学生的数据。
// It terminates input upon filling the array pr upon encountering a blank line for the student name.
// 它在遇到学生姓名的空行时填写数组pr时终止输入。
// The function returns the actual number of array element filled.
// 该函数返回填充的数组元素的实际数量。
// display1() takes a student structures as an argument and displays its contents
// display1() 将student结构作为参数并显示其内容
// display3() takes the address of the first element of an array of student structures and
// the number of number of array element as arguements and displays the contents of the structures
// display3()将student结构数组的第一个元素的地址和数组元素的数量作为参数,并显示结构的内容
void Xiti9()//
{
return;
}
/*
设计一个名为calculate()的函数,接受两个double值和一个指向函数的指针,而被指向的函数接受两个double参数,并返回一个double值。
calculate()函数的类型也是double,并返回被指向的函数使用calculate()的两个double参数计算得到的值。例如,假设add()函数的定义如下:
double add(double x, double y)
{
return x + y;
}
则下述代码中的函数调用将导致calculate()把2.5 和10.4 传递给add()函数,并返回add()的返回值(12.9):
double q = calculate(2.5, 10.4, add);
请编写一个程序,它调用上述两个函数和至少另一个与add()类似的函数。该程序使用循环来让用户成对地数入数字。
对于每一个数字,程序都使用calculate()来调用add()和至少一个其他的函数。
如果读者爱冒险,可以尝试创建一个指针数组,其中的指针指向add()样式的函数,并编写一个循环。 使用这些指针连续让calculate()调用这些函数。
提示:声明这种指针数组的方式为: double (*pf[3])(double, double); 其中包含三个指针
可以采用数组初始化语法,并将函数名作为地址来初始化这样的数组。
*/
void Xiti10()//
{
return;
}
void Xiti10_2()//
{
return;
}
int main()
{
int XitiNo = 1;//输入习题编号
cout << "第四章编程练习答案:\n";
cout << "请输入习题编号或按(0)退出:\n";
cin >> XitiNo;
while (XitiNo != 0)
{
if (cin)//输入合法则执行
{
if (XitiNo >= 0 && XitiNo <= 10)
{
switch (XitiNo)
{
case 0:
{
cout << "即将退出程序啦!\n";
}break;
case 1:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti1();
}break;
case 2:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti2();
}break;
case 3:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti3();
}break;
case 4:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti4();
}break;
case 5:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti5();
}break;
case 6:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti6();
}break;
case 7:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti7();
}break;
case 8:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti8();
}break;
case 9:
{
cout << "第" << XitiNo << "题如下:\n";
Xiti9();
}break;
case 10:
{
cout << "第" << XitiNo << "题如下:\n";
//Xiti10();
Xiti10_2();
}break;
default:
{
cout << "即将退出程序啦\n";
XitiNo = 0;
}
break;
}
cout << "继续查看请输入习题编号或按(0)退出:\n";
cin >> XitiNo;
}
else
{
cout << "没有这样的编号\n继续查看请输入习题编号或按(0)退出:\n";
cin >> XitiNo;
}
}
else//输入不合法则重新输入
{
XitiNo = 0;
}
}
system("pause");//为了程序能够停下看看。
return 0;
}
C++ primer Plus(第六版)第八章函数探幽编程答案
最新推荐文章于 2021-07-18 12:55:14 发布