C++学习之路(七),C++primer plus 第八章 函数探幽 - 复习题
------------恢复内容开始------------
------------恢复内容开始------------
------------恢复内容开始------------
8.7 复习题
1. 哪种函数适合定义为内联函数?
经常被调用,逻辑简单,代码少,没有递归,没有循环的函数。
2. 假设 song()函数的原型如下:
void song(const char * name, int times);
a. 如何修改原型,使 times 的默认值为 1?
void song(const char * name, int times = 1);
c. 函数定义需要做哪些修改?
函数定义不需要作修改。
d. 能否为 name 提供默认值 “O.My Papa"?
void song(const * name = "O.My Papa", int time = 1);
编写 iquote()的重载版本 ---- 显示其用双引号括起的参数。编写 3 个版本:一个用于 int 参数,
#include<iostream> using namespace std; void iquote(int); int main() { iquote(5); return 0; } void iquote(int a); { cout << "\"" << a << "\"" << endl; }
效果
一个用于 double 参数,
#include<iostream> using namespace std; void iquote(double); int main() {
iquote(3.1415926); return 0; } void iquote(double x) {
cout << "\"" << x << "\"" << endl; }
运行效果如下:
另一个用于 string 参数。
#include<iostream> using namespace std;
/* void iquote(string); // 不知为何这个代码不可运行 int main() {
iquote("i'm C++er");
return 0; } void iquote(string i) {
cout << "\"" << i << "\"" << endl; }
*/
void iquote(char *)
int main()
{
iquote("i'm C++er");
return 0;
}
void iquote(char * str)
{
cout << '"' << str << "\"" << endl;
}
4.下面是一个结构模板:
struct box { char maker[ 40 ];
float height;
float width;
float length;
float volume; };
a. 请编写一个函数,它将 box 结构的引用作为形参,并显示每个成员的值。
#include <iostream> using namespace std; struct box { char maker[ 40 ];
float height;
float width;
float length;
float volume; };
void display_box(const box & b_ox);
void set_box(box & b_ox);
int main()
{
box b = {"Ok~Good", 35.6, 36.5, 65.3, 63.5};
display(b);
return 0;
}
void display(const box & b_ox)
{
cout << "maker: " << b_ox.maker << endl;
cout << "height: " << b_ox.height << endl;
cout << "width: " << b_ox.width << endl;
cout << "length: " << b_ox.length << endl;
cout << "volume: " << b_ox.volume << endl;
}
b. 请编写一个函数,它将 box 结构的引用作为形参,并将 volume 成员设置为其他 3 边的乘积。
#include <iostream> using namespace std; struct box { char maker[ 40 ]; float height; float width; float length; float volume; }; void display_box(const box & b_ox); void set_box(box & b_ox); int main() { box b = {"Ok~Good", 35.6, 36.5, 65.3}; // 删除给结构成员 volume 赋值时还担心这里不能运行,结果,没事 display(b); return 0; } void display(const box & b_ox) { cout << "maker: " << b_ox.maker << endl; cout << "height: " << b_ox.height << endl; cout << "width: " << b_ox.width << endl; cout << "length: " << b_ox.length << endl; cout << "volume: " << b_ox.height * b_ox.width * b_ox.length << endl;
}
代码运行结果如下:
5. 为让函数 fill() 和show() 使用引用参数,需要对程序清单 7.15 做哪些修改?
原代码为:
// arrobj.cpp -- functions with array objects (C++11) #include <iostream> #include <array> #include <string> // constant data const int Seasons = 4; const std::array<std::string, Seasons> Snames = {"Spring", "Summer", "Fall", "Winter"}; // function to modify array object void fill(std:: array<double, Seasons> * pa); // function that uses array object without modifying it void show(std:: array<double, Seasons> da); int main() { std::array<double, Seasons> expenses;
fill(&expenses); // 当形参为指针,调用的时候要用取地址符
show(expenses);
return 0; }
void fill(std::array<double, Seasons> *pa)
{
using namespace std;
for(int i = 0; i < Seasons; i ++)
{
cout << "Enter " << Snames[ i ] << " expenses: ";
cin >> (*pa)[ i ];
}
}
void show(std:: array<double, Seasons> da
{
using namespace std;
double total = 0.0;
cout << "\nEXPENSES\n";
for(int i = o; i < Seasons; i ++)
{
cout << Snames[ i ] << : $" << da[ i ] << endl;
total + = da[ i ];
}
cout << "Total Exenses: $" << total << endl;
}
修改代码为:
// arrobj.cpp -- functions with array objects (C++11) #include <iostream> #include <array> #include <string> // constant data const int Seasons = 4; const std::array<std::string, Seasons> Snames = {"Spring", "Summer", "Fall", "Winter"}; // function to modify array object void fill(std::array<double, Seasons> & pa); // 这里修改为 & pa // function that uses array object without modfyint it void show(std:: array<double, Seasons> & da); // 这里修改为 & da int main() { std::array<double, Seasons> expenses; fill(expenses); // 当形参为引用时,调用直接用引用的名称 show(expenses); return 0; } void fill(std::array<double, Seasons> & pa) // 这里改为 引用 & pa { using namespace std; for(int i = 0; i < Seasons; i ++) { cout << "Enter " << Snames[ i ] << "expeneses: "; cin >> (pa) [ i ]; // 将 cin >> (*pa) [ i ]; 修改为 cin >> (pa) [ i ]; } } void show(std::array<double, Seasons> & da) // 这里改为引用 & da { using namespace std; double total = 0.0; cout << "\nEXPENSES\n"; for(int i = 0; i < Seasons; i ++) { cout << Snames[ i ] << ": $" << da[ i ] << endl; total += da[ i ]; } cout << "Total Expenses: $" << total << endl; }
程序运行如下:
6,指出下面的每个目标是否可以使用默认参数或函数重载完成,或者这两种方法都无法完成,并提供合适的原型。
a,mass(density, volume)返回密度为 density、体积为 volume 的物体的质量,而 mass(denstity) 返回密度为 density、体积为 1.0 立方米的物体的质量。这些值的类型都是 double。
既可以使用默认参数
void mass(double density, double volume = 1.0);
又可以使用函数重载
void mass(double density, double volume); void mass(double density);
b,repeat(10, "I'm OK")将指定的字符串显示 10 次,而 repeat("But you're kind of stupid")将指定的字符串显示 5 次。
不能使用默认值,因为使用默认值必须从右向左提供默认值,函数重载代码:
void repeat (int times, char * str); void repeat (const char * str);
c,average(3, 6) 返回两个 int 参数的平均值( int类型),而 average(3.0, 6.0) 返回两个 double 值的平均值 (double类型)。
使用函数重载
int average(int n, int m); double average(double i , double j);
d,mangle("I'm glad to meet you")根据是将值赋值给 char 变量还是 char * 变量,分别返回字符 I 和指向字符串“I‘m mad to gleet you" 的指针。
不能实现,因为两种方法的特征标将相同,需要分成不同的函数实现
7,编写返回两个参数中较大值的函数模板。
#include <iostream> using namespace std; template<typename T> // template<class T1, class T2> void compare(T x, T y) // void compare(T1 x, T2 y) { cout << (x > y ? x : y) << endl; } int main() { compare(3, 5);
return 0; }
运行结果:
8,给定复习题 6 的模板和复习题 4 的 box 结构,提供一个模板具体化,它接受两个 box 参数,并返回体积校大的一个。
#include <iostream> using namespace std; template<typename T> void max(T & a, T & b); struct box { char maker[ 40 ]; float height; float width; float length; float volume; }; template<> void max<box>(box & b1, box & b2); void showbox(box & b); int main() { box b1 = {"maker1", 30.0, 40.0, 50.0, b1.height * b1.width * b1.length}; box b2 = {"maker2", 25.0, 25.0, 25.0, b2.height * b2.width * b2.length}; showbox(b1); showbox(b2); max(b1, b2); // 调用的时候直接写结构名就行了,不需要 box & b1 return 0; } void showbox(box & b) { cout << "b.maker: " << b.maker << endl; cout << "b.height: " << b.height << endl; cout << "b.width: " << b.width << endl; cout << "b.length: " << b.length << endl; cout << "b.volume: " << b.volume << endl << endl; } template<> void max<box>(box & b1, box & b2) { cout << endl << "The bigger volume is: " << (b1.volume > b2.volume ? b1.volume : b2.volume) << endl; }
备注:看了下网上好多都是用
template <> box max(box b1, box b2) { return b1.volume > b2.volume ? b1 : b2; }
这一段代码,不过可能是我技术不过关,用这一段代码程序不能运行,总是提示不能将 float 转换为 struct box,不知道是何解,只有借了用程序清单 8.13 中的代码。
9.在下述代码(假定这些代码是一个完整程序的一部分)中,v1、v2、v3、v4 和 v5 分别是哪种类型?
int g(int x); ... float m = 5.5f; float & rm = m; decltype(m) v1 = m; decltype(rm) v2 = m; decltype((m)) v3 = m; decltype(g(100)) v4 ; decltype(2.0 * m) v5;
------------恢复内容开始------------
------------恢复内容开始------------
------------恢复内容开始------------
------------恢复内容开始------------
8.7 复习题
1. 哪种函数适合定义为内联函数?
经常被调用,逻辑简单,代码少,没有递归,没有循环的函数。
2. 假设 song()函数的原型如下:
void song(const char * name, int times);
a. 如何修改原型,使 times 的默认值为 1?
void song(const char * name, int times = 1);
c. 函数定义需要做哪些修改?
函数定义不需要作修改。
d. 能否为 name 提供默认值 “O.My Papa"?
void song(const * name = "O.My Papa", int time = 1);
编写 iquote()的重载版本 ---- 显示其用双引号括起的参数。编写 3 个版本:一个用于 int 参数,
#include<iostream> using namespace std; void iquote(int); int main() { iquote(5); return 0; } void iquote(int a); { cout << "\"" << a << "\"" << endl; }
效果
一个用于 double 参数,
#include<iostream> using namespace std; void iquote(double); int main() {
iquote(3.1415926); return 0; } void iquote(double x) {
cout << "\"" << x << "\"" << endl; }
运行效果如下:
另一个用于 string 参数。
#include<iostream> using namespace std;
/* void iquote(string); // 不知为何这个代码不可运行 int main() {
iquote("i'm C++er");
return 0; } void iquote(string i) {
cout << "\"" << i << "\"" << endl; }
*/
void iquote(char *)
int main()
{
iquote("i'm C++er");
return 0;
}
void iquote(char * str)
{
cout << '"' << str << "\"" << endl;
}
4.下面是一个结构模板:
struct box { char maker[ 40 ];
float height;
float width;
float length;
float volume; };
a. 请编写一个函数,它将 box 结构的引用作为形参,并显示每个成员的值。
#include <iostream> using namespace std; struct box { char maker[ 40 ];
float height;
float width;
float length;
float volume; };
void display_box(const box & b_ox);
void set_box(box & b_ox);
int main()
{
box b = {"Ok~Good", 35.6, 36.5, 65.3, 63.5};
display(b);
return 0;
}
void display(const box & b_ox)
{
cout << "maker: " << b_ox.maker << endl;
cout << "height: " << b_ox.height << endl;
cout << "width: " << b_ox.width << endl;
cout << "length: " << b_ox.length << endl;
cout << "volume: " << b_ox.volume << endl;
}
b. 请编写一个函数,它将 box 结构的引用作为形参,并将 volume 成员设置为其他 3 边的乘积。
#include <iostream> using namespace std; struct box { char maker[ 40 ]; float height; float width; float length; float volume; }; void display_box(const box & b_ox); void set_box(box & b_ox); int main() { box b = {"Ok~Good", 35.6, 36.5, 65.3}; // 删除给结构成员 volume 赋值时还担心这里不能运行,结果,没事 display(b); return 0; } void display(const box & b_ox) { cout << "maker: " << b_ox.maker << endl; cout << "height: " << b_ox.height << endl; cout << "width: " << b_ox.width << endl; cout << "length: " << b_ox.length << endl; cout << "volume: " << b_ox.height * b_ox.width * b_ox.length << endl;
}
代码运行结果如下:
5. 为让函数 fill() 和show() 使用引用参数,需要对程序清单 7.15 做哪些修改?
原代码为:
// arrobj.cpp -- functions with array objects (C++11) #include <iostream> #include <array> #include <string> // constant data const int Seasons = 4; const std::array<std::string, Seasons> Snames = {"Spring", "Summer", "Fall", "Winter"}; // function to modify array object void fill(std:: array<double, Seasons> * pa); // function that uses array object without modifying it void show(std:: array<double, Seasons> da); int main() { std::array<double, Seasons> expenses;
fill(&expenses); // 当形参为指针,调用的时候要用取地址符
show(expenses);
return 0; }
void fill(std::array<double, Seasons> *pa)
{
using namespace std;
for(int i = 0; i < Seasons; i ++)
{
cout << "Enter " << Snames[ i ] << " expenses: ";
cin >> (*pa)[ i ];
}
}
void show(std:: array<double, Seasons> da
{
using namespace std;
double total = 0.0;
cout << "\nEXPENSES\n";
for(int i = o; i < Seasons; i ++)
{
cout << Snames[ i ] << : $" << da[ i ] << endl;
total + = da[ i ];
}
cout << "Total Exenses: $" << total << endl;
}
修改代码为:
// arrobj.cpp -- functions with array objects (C++11) #include <iostream> #include <array> #include <string> // constant data const int Seasons = 4; const std::array<std::string, Seasons> Snames = {"Spring", "Summer", "Fall", "Winter"}; // function to modify array object void fill(std::array<double, Seasons> & pa); // 这里修改为 & pa // function that uses array object without modfyint it void show(std:: array<double, Seasons> & da); // 这里修改为 & da int main() { std::array<double, Seasons> expenses; fill(expenses); // 当形参为引用时,调用直接用引用的名称 show(expenses); return 0; } void fill(std::array<double, Seasons> & pa) // 这里改为 引用 & pa { using namespace std; for(int i = 0; i < Seasons; i ++) { cout << "Enter " << Snames[ i ] << "expeneses: "; cin >> (pa) [ i ]; // 将 cin >> (*pa) [ i ]; 修改为 cin >> (pa) [ i ]; } } void show(std::array<double, Seasons> & da) // 这里改为引用 & da { using namespace std; double total = 0.0; cout << "\nEXPENSES\n"; for(int i = 0; i < Seasons; i ++) { cout << Snames[ i ] << ": $" << da[ i ] << endl; total += da[ i ]; } cout << "Total Expenses: $" << total << endl; }
程序运行如下:
6,指出下面的每个目标是否可以使用默认参数或函数重载完成,或者这两种方法都无法完成,并提供合适的原型。
a,mass(density, volume)返回密度为 density、体积为 volume 的物体的质量,而 mass(denstity) 返回密度为 density、体积为 1.0 立方米的物体的质量。这些值的类型都是 double。
既可以使用默认参数
void mass(double density, double volume = 1.0);
又可以使用函数重载
void mass(double density, double volume); void mass(double density);
b,repeat(10, "I'm OK")将指定的字符串显示 10 次,而 repeat("But you're kind of stupid")将指定的字符串显示 5 次。
不能使用默认值,因为使用默认值必须从右向左提供默认值,函数重载代码:
void repeat (int times, char * str); void repeat (const char * str);
c,average(3, 6) 返回两个 int 参数的平均值( int类型),而 average(3.0, 6.0) 返回两个 double 值的平均值 (double类型)。
使用函数重载
int average(int n, int m); double average(double i , double j);
d,mangle("I'm glad to meet you")根据是将值赋值给 char 变量还是 char * 变量,分别返回字符 I 和指向字符串“I‘m mad to gleet you" 的指针。
不能实现,因为两种方法的特征标将相同,需要分成不同的函数实现
7,编写返回两个参数中较大值的函数模板。
#include <iostream> using namespace std; template<typename T> // template<class T1, class T2> void compare(T x, T y) // void compare(T1 x, T2 y) { cout << (x > y ? x : y) << endl; } int main() { compare(3, 5);
return 0; }
运行结果:
8,给定复习题 6 的模板和复习题 4 的 box 结构,提供一个模板具体化,它接受两个 box 参数,并返回体积校大的一个。
#include <iostream> using namespace std; template<typename T> void max(T & a, T & b); struct box { char maker[ 40 ]; float height; float width; float length; float volume; }; template<> void max<box>(box & b1, box & b2); void showbox(box & b); int main() { box b1 = {"maker1", 30.0, 40.0, 50.0, b1.height * b1.width * b1.length}; box b2 = {"maker2", 25.0, 25.0, 25.0, b2.height * b2.width * b2.length}; showbox(b1); showbox(b2); max(b1, b2); // 调用的时候直接写结构名就行了,不需要 box & b1 return 0; } void showbox(box & b) { cout << "b.maker: " << b.maker << endl; cout << "b.height: " << b.height << endl; cout << "b.width: " << b.width << endl; cout << "b.length: " << b.length << endl; cout << "b.volume: " << b.volume << endl << endl; } template<> void max<box>(box & b1, box & b2) { cout << endl << "The bigger volume is: " << (b1.volume > b2.volume ? b1.volume : b2.volume) << endl; }
备注:看了下网上好多都是用
template <> box max(box b1, box b2) { return b1.volume > b2.volume ? b1 : b2; }
这一段代码,不过可能是我技术不过关,用这一段代码程序不能运行,总是提示不能将 float 转换为 struct box,不知道是何解,只有借了用程序清单 8.13 中的代码。
9.在下述代码(假定这些代码是一个完整程序的一部分)中,v1、v2、v3、v4 和 v5 分别是哪种类型?
int g(int x); ... float m = 5.5f; float & rm = m; decltype(m) v1 = m; // v1 类型是 float decltype(rm) v2 = m; // v2 类型是 float & decltype((m)) v3 = m; // v3 类型是 float & decltype(g(100)) v4; // v4 类型是 int decltype(2.0 * m) v5; // v5 类型是 double

浙公网安备 33010602011771号