1 /*********************************************************************
2 程序名:8.7 复习题
3 版权:
4 作者: 大野狼
5 日期: 2022/4/23-星期六 10:41:35
6 说明:
7 *********************************************************************/
8 #include <iostream>
9 int main(void) {
10 using namespace std;
11 return 0;
12 }
13
14 8.7 复习题
15 1. 哪种函数适合定义为内联函数?
16 答:反复利用,短代码,非递归。
17
18 2. 假设song( )函数的原型如下:
19 void song(const char * name, int times);
20 a. 如何修改原型, 使times的默认值为1?
21 void song(const char * name, int times=1);
22 b. 函数定义需要做哪些修改?
23 答;无需修改
24 c. 能否为name提供默认值“O. My Papa”?
25 void song(int times, const char * name="O. My Papa");
26
27 3. 编写iquote( )的重载版本——显示其用双引号括起的参数。 编写
28 3个版本: 一个用于int参数, 一个用于double参数, 另一个用于string参
29 数。
30 iquote(int x);
31 iquote(double x);
32 iquote(string x);
33
34 4. 下面是一个结构模板:
35 struct box{
36 char maker[40];
37 float height;
38 float width;
39 float length;
40 float volume;
41 };
42 a. 请编写一个函数, 它将box结构的引用作为形参, 并显示每个成
43 员的值。
44 void fun1(const box & box1)
45 {
46 cout<<box1.maker<<endl;
47 cout<<box1.height<<endl;
48 cout<<box1.width<<endl;
49 cout<<box1.length<<endl;
50 cout<<box1.volume<<endl;
51 }
52 b. 请编写一个函数, 它将box结构的引用作为形参, 并将volume成
53 员设置为其他3边的乘积。
54 void fun2(box & box1)
55 {
56 box1.volume = box1.height * box1.width * box1.length
57 }
58
59 5. 为让函数fill()和show()使用引用参数, 需要对程序清单7.15做哪
60 些修改?
61 void fill(std::array<double, Seasons> * pa); //原函数
62 void fill(std::array<double, Seasons> & pa); //改为引用
63
64
65 void show(std::array<double, Seasons> da); //原函数
66 void show(const std::array<double, Seasons> & da); //改为引用
67
68 6. 指出下面每个目标是否可以使用默认参数或函数重载完成, 或
69 者这两种方法都无法完成, 并提供合适的原型。
70 a. mass(density, volume)返回密度为density、 体积为volume的物体
71 的质量, 而mass(denstity)返回密度为density、 体积为1.0立方米的物体的
72 质量。 这些值的类型都为double。
73 double mass(double density,double volume=1.0):
74
75 b. repeat(10, “I'm OK”)将指定的字符串显示10次, 而repeat(“But
76 you're kind of stupid”)将指定的字符串显示5次。
77 void repeat(int n , const char * ar);
78 void repeat(const char * ar , int n=5);
79
80 c. average(3, 6)返回两个int参数的平均值(int类型) , 而
81 average(3.0, 6.0)返回两个double值的平均值(double类型) 。
82 int average(int x,int y);
83 double average(double x,double y);
84
85 d. mangle(“I'm glad to meet you”)根据是将值赋给char变量还是char*
86 变量, 分别返回字符I和指向字符串“I'm mad to gleet you”的指针。
87 答:不能 特征值相同。
88
89 7. 编写返回两个参数中较大值的函数模板。
90 template <typename T>
91 T lage(const T x,const T y)
92 {
93 return x>y?x:y;
94 }
95
96 8. 给定复习题6的模板和复习题4的box结构, 提供一个模板具体
97 化, 它接受两个box参数, 并返回体积较大的一个。
98 template<>box max(box b1,box b2)
99 {
100 return b1.volume>b2.volume?b1:b2;
101 }
102
103 9. 在下述代码(假定这些代码是一个完整程序的一部分) 中,
104 v1、 v2、 v3、 v4和v5分别是哪种类型?
105 int g(int x);
106 ...
107 float m=5.5f;
108 float & rm = m;
109 defltype(m) v1=m; float
110 defltype(rm) v2=m; float &
111 defltype((m)) v3=m; float &
112 defltype(g(100)) v4; int
113 defltype(2.0 * m) v5; double 2.0为double类型
114
115
116
117
118
119
120
121
122
1 /*********************************************************************
2 程序名:8.8 编程练习
3 1. 编写通常接受一个参数(字符串的地址) , 并打印该字符串的
4 函数。 然而, 如果提供了第二个参数(int类型) , 且该参数不为0, 则
5 该函数打印字符串的次数将为该函数被调用的次数(注意, 字符串的打
6 印次数不等于第二个参数的值, 而等于函数被调用的次数) 。 是的, 这
7 是一个非常可笑的函数, 但它让您能够使用本章介绍的一些技术。 在一
8 个简单的程序中使用该函数, 以演示该函数是如何工作的。
9 版权:
10 作者: 大野狼
11 日期: 2022/4/23-星期六 14:17:17
12 说明:
13 *********************************************************************/
14 #include <iostream>
15 using namespace std;
16 void print_str(char * a,int n=1);
17
18 int main(void) {
19 char * str = "wang xin yang";
20 print_str(str,-5);
21 return 0;
22 }
23
24 void print_str(char * a,int n)
25 {
26 n<1?n=1:1;
27 for(int i=0;i<n;++i)
28 {
29 cout<<a<<endl;
30 }
31 }
1 /*********************************************************************
2 程序名:2. CandyBar结构包含3个成员。 第一个成员存储candy bar的品牌名
3 称; 第二个成员存储candy bar的重量(可能有小数) ; 第三个成员存储
4 candy bar的热量(整数) 。 请编写一个程序, 它使用一个这样的函数,
5 即将CandyBar的引用、 char指针、 double和int作为参数, 并用最后3个值
6 设置相应的结构成员。 最后3个参数的默认值分别为“Millennium
7 Munch”、 2.85和350。 另外, 该程序还包含一个以CandyBar的引用为参
8 数, 并显示结构内容的函数。 请尽可能使用const。
9 版权:
10 作者: 大野狼
11 日期: 2022/4/23-星期六 14:48:34
12 说明:
13 *********************************************************************/
14 #include <iostream>
15 //#include <string>
16 #include <cstring>
17 using namespace std;
18 const int Size=80;
19
20 struct CandyBar{
21 // string brand;
22 char brand[Size]; //品牌
23 float weight; //重量
24 int count; //数量
25 };
26
27 void fill(CandyBar & c1,char * ch="Millennium Munch",double d1=2.85,int n1=350);
28 void print(const CandyBar & c1);
29
30 int main(void) {
31 CandyBar cand[5];
32 fill(cand[0],"娃哈哈",0.856,25);
33 fill(cand[1],"金箍棒",13500,1);
34 fill(cand[2]);
35 cout<<"\n*****************\n"<<endl;
36 print(cand[0]);
37 print(cand[1]);
38 print(cand[2]);
39 return 0;
40 }
41
42 void fill(CandyBar & c1,char * ch,double d1,int n1)
43 {
44 strcpy(c1.brand,ch);
45 c1.weight = d1;
46 c1.count = n1;
47 // cout<<"brand:";
48 // cin.getline(c1.brand,Size);
49 // cout<<"weight:";
50 // cin>>c1.weight;
51 // cin.get();
52 // cout<<"count:";
53 // cin>>c1.count;
54 // cin.get();
55 }
56 void print(const CandyBar & c1)
57 {
58 cout<<"brand: "<<c1.brand<<endl;
59 cout<<"weight: "<<c1.weight<<endl;
60 cout<<"count: "<<c1.count<<endl;
61 }
1 /*********************************************************************
2 程序名:3. 编写一个函数, 它接受一个指向string对象的引用作为参数, 并
3 将该string对象的内容转换为大写, 为此可使用表6.4描述的函数toupper(
4 )。 然后编写一个程序, 它通过使用一个循环让您能够用不同的输入来
5 测试这个函数, 该程序的运行情况如下:
6 版权:
7 作者: 大野狼
8 日期: 2022/4/23-星期六 15:51:18
9 说明:
10 *********************************************************************/
11 #include <iostream>
12 #include <string>
13 using namespace std;
14 void upper(const string & str1);
15 int main(void) {
16 cout<<"请输入一段小写的字符串(q退出):\n";
17 string str1;
18 getline(cin,str1);
19 while(str1!="q")
20 {
21 upper(str1);
22 cout<<"\n再次输入字符串:\n";
23 getline(cin,str1);
24 }
25 cout<<"收工!"<<endl;
26 return 0;
27 }
28
29 void upper(const string & str1){
30 int count = str1.size();
31 char ch;
32 for(int i=0;i<count;++i)
33 {
34 ch = (str1[i]>='a' && str1[i]<='z')? str1[i]-32:str1[i];
35 cout<<ch;
36 }
37 }
1 /*********************************************************************
2 程序名:4. 下面是一个程序框架:
3 请提供其中描述的函数和原型, 从而完成该程序。 注意, 应有两个
4 show( )函数, 每个都使用默认参数。 请尽可能使用cosnt参数。 set( )使用
5 new分配足够的空间来存储指定的字符串。 这里使用的技术与设计和实
6 现类时使用的相似。 (可能还必须修改头文件的名称, 删除using编译指
7 令, 这取决于所用的编译器。 )
8 版权:
9 作者: 大野狼
10 日期: 2022/4/23-星期六 16:58:55
11 说明:
12 *********************************************************************/
13 #include <iostream>
14 #include <string>
15 #include <cstring>
16 using namespace std;
17
18 struct stringy {
19 char *str;
20 int ct;
21 };
22 void set(struct stringy &in_stringy, char * in_string);
23 void show(const struct stringy &in_stringy, int print_times = 1);
24 void show(const char * str, int print_times = 1);
25
26 int main(void) {
27
28 stringy beany;
29 char testing[] = "Reality isn't what it used to be.";
30
31 set(beany, testing);
32 show(beany);
33 show(beany, 2);
34 int i = 1+2;
35 cout<<"************"<<beany.str<<endl;
36 // delete [] beany.str;
37 // cout<<"************"<<beany.str<<endl;
38 testing[0] = 'D';
39 testing[1] = 'u';
40 show(testing);
41 show(testing, 3);
42 show("Done!");
43 return 0;
44 }
45
46
47
48 void set(struct stringy &in_stringy, char * in_string)
49 {
50 int string_length = strlen(in_string);
51 in_stringy.str = new char(string_length + 1);
52 strcpy(in_stringy.str, in_string);
53 in_stringy.ct = string_length;
54 }
55 void show(const struct stringy &in_stringy, int print_times)
56 {
57 for (int i = 0; i < print_times; i++)
58 {
59 cout << "member string of struct stringy: " << in_stringy.str << endl;
60 }
61 }
62 void show(const char * str, int print_times)
63 {
64 for (int i = 0; i < print_times; i++)
65 {
66 cout << "Print char string: " << str << endl;
67 }
68 }
1 /*********************************************************************
2 程序名:5. 编写模板函数max5( ), 它将一个包含5个T类型元素的数组作为
3 参数, 并返回数组中最大的元素(由于长度固定, 因此可以在循环中使
4 用硬编码, 而不必通过参数来传递) 。 在一个程序中使用该函数, 将T
5 替换为一个包含5个int值的数组和一个包含5个dowble值的数组, 以测试
6 该函数。
7 版权:
8 作者: 大野狼
9 日期: 2022/4/24-星期日 10:46:26
10 说明:
11 *********************************************************************/
12 #include <iostream>
13 using namespace std;
14 template<typename T>
15 void max5(T arr[],int n);
16 int main(void) {
17 int arr[5]={5,6,8,99,4};
18 double arr2[5]={5.1,666.1,8.2,99.0,1.4};
19
20 max5(arr,5);
21 max5(arr2,5);
22
23 return 0;
24 }
25
26
27 template<typename T>
28 void max5(T arr[],int n)
29 {
30 T max=arr[0];
31 for(int i=1;i<n;++i)
32 (max<arr[i])?(max=arr[i]):1;
33 cout<<max<<endl;
34 }
1 /*********************************************************************
2 程序名:6. 编写模板函数maxn( ), 它将由一个T类型元素组成的数组和一
3 个表示数组元素数目的整数作为参数, 并返回数组中最大的元素。 在程
4 序对它进行测试, 该程序使用一个包含6个int元素的数组和一个包含4个
5 double元素的数组来调用该函数。 程序还包含一个具体化, 它将char指
6 针数组和数组中的指针数量作为参数, 并返回最长的字符串的地址。 如
7 果有多个这样的字符串, 则返回其中第一个字符串的地址。 使用由5个
8 字符串指针组成的数组来测试该具体化。
9 版权:
10 作者: 大野狼
11 日期: 2022/4/24-星期日 11:20:15
12 说明:
13 *********************************************************************/
14 #include <iostream>
15 #include <string>
16 #include <cstring>
17 using namespace std;
18 template<typename T>
19 void max5(T arr[],int n);
20 template <> void max5(char *arr[],int n);
21 int main(void) {
22 int arr[6]={5,6,8,99,4,45};
23 double arr2[4]={5.1, 666.1, 8.2, 99.0};
24 char * arr3[5]={"yangggg","xin","yangggg","john","ha"};
25
26 max5(arr,6);
27 max5(arr2,4);
28 max5(arr3,5);
29
30 return 0;
31 }
32
33
34 template <> void max5(char *arr[],int n)
35 {
36 int count=strlen(arr[0]);
37 int index=1;
38 for(int i = 0;i<n;++i)
39 (count<strlen(arr[i]))?count=strlen(arr[i]),index=i+1:1;
40 cout<<index<<endl;
41 }
42
43 template<typename T>
44 void max5(T arr[],int n)
45 {
46 // cout<<sizeof(arr)/sizeof(arr[0])<<endl;
47 T max=arr[0];
48 for(int i=1;i<n;++i)
49 (max<arr[i])?(max=arr[i]):1;
50 cout<<max<<endl;
51 }
1 /*********************************************************************
2 程序名:7. 修改程序清单 8.14, 使其使用两个名为 SumArray()的模板函数
3 来返回数组元素的总和, 而不是显示数组的内容。 程序应显示thing的总
4 和以及所有debt的总和。
5 版权:
6 作者: 大野狼
7 日期: 2022/4/24-星期日 14:07:31
8 说明:
9 *********************************************************************/
10 // 8.14 tempover.cpp --- template overloading
11 #include <iostream>
12 template <typename T> // template A
13 void SumArray(T arr[], int n);
14 template <typename T> // template B
15 void SumArray(T * arr[], int n);
16
17 struct debts
18 {
19 char name[50];
20 double amount;
21 };
22
23 int main()
24 {
25 using namespace std;
26 int things[6] = {13, 31, 103, 301, 310, 130};
27 struct debts mr_E[3] = {
28 {"Ima Wolfe", 2400.0},
29 {"Ura Foxe", 1300.0},
30 {"Iby Stout", 1800.0}};
31 double * pd[3];
32
33 // set pointers to the amount members of the structures in mr_E
34 for (int i = 0; i < 3; i++)
35 pd[i] = &mr_E[i].amount;
36
37 cout << "Listing Mr. E's counts of things:\n";
38 // things is an array of int
39 SumArray(things, 6); // uses template A
40 cout << "Listing Mr. E's debts:\n";
41 // pd is an array of pointers to double
42 SumArray(pd, 3); // uses template B (more specialized)
43 // cin.get();
44 return 0;
45 }
46
47 template <typename T>
48 void SumArray(T arr[], int n)
49 {
50 using namespace std;
51 T sum=0;
52 cout << "template A\n";
53 for (int i = 0; i < n; i++)
54 sum += arr[i];
55 cout << sum << endl;
56 }
57
58 template <typename T>
59 void SumArray(T * arr[], int n)
60 {
61 T sum=0;
62 using namespace std;
63 cout << "template B\n";
64 for (int i = 0; i < n; i++)
65 sum += *arr[i];
66 cout << sum << endl;
67 }