Chapter 8
8.1
#include<iostream>
using namespace std;
void show(char * ch, int n = 0);
int main()
{
char ch[10] = "A B C\n";
for (int i = 0; i < 5; ++i)
{
cout << i << endl;
show(ch, i);
}
cin.get();
cin.get();
}
void show(char * ch, int n)
{
static int count = 0;
int lim = ++count;
if (n == 0)
lim = 1;
for (int i = 0; i < lim; ++i)
{
cout << ch;
}
}
重要知识点:static的用法,在这里可以在函数内部实现记录函数调用的次数。
8.2
#include<iostream>
using namespace std;
const int SIZE = 30;
struct CandyBar
{
char name[SIZE];
double weight;
int heat;
};
void fill(CandyBar & c, const char * name = "Millennium Munch", const double weight = 2.85, const int heat = 350);
void Show(const CandyBar & c);
int main()
{
CandyBar candy = {"void", 0.0, 0};
fill(candy);
Show(candy);
cin.get();
cin.get();
}
void fill(CandyBar & c, const char * name, const double weight, const int heat)
{
int i = 0;
while (name[i])
{
c.name[i] = name[i];
++i;
}
while (i < SIZE)
{
c.name[i] = '\0';
++i;
}
c.weight = weight;
c.heat = heat;
}
void Show(const CandyBar & c)
{
cout << "name of CandyBar: " << c.name << endl;
cout << "weight of CandyBar: " << c.weight << endl;
cout << "heat of CandyBar: " << c.heat << endl;
}
重要知识点:①. 函数默认值必须从右向左设置; ②. 可以直接输入数据源类型作为函数引用类型, 比如这里candy作为 candy &输入.
8.3
#include<iostream>
#include<cctype>
#include<string>
using namespace std;
void L2U(string & str);
int main()
{
string str, q = "q";
cout << "Enter a string (qto quit): ";
getline(cin, str);
while (str != q)
{
L2U(str);
cout << str << endl;
cout << "Next string (q to quit): ";
getline(cin, str);
}
cout << "Bye.";
cin.get();
cin.get();
}
void L2U(string & str)
{
int n = str.length();
for (int i = 0; i < n; ++i)
{
str[i] = toupper(str[i]);
}
}
重要知识点: ①. getline(cin, str) 读取整行字符; ②. string.length()返回string长度; ③. toupper( )只能接受单个字符.
8.4
#include<iostream>
#include<cstring>
using namespace std;
struct stringy
{
char * str;
int ct;
};
void set(stringy & stri, const char * ch);
void show(const stringy stri, const int n = 1);
void show(const char * ch, int n = 1);
int main()
{
stringy beany;
char testing[] = "Reality isn't what it used to be.";
set(beany, testing);
show(beany);
show(beany, 2);
testing[0] = 'D';
testing[1] = 'u';
show(testing);
show(testing, 3);
show("Done!");
cin.get();
cin.get();
return 0;
}
void set(stringy & stri, const char * ch)
{
int len = strlen(ch);
char * st = new char[len + 1];
stri.str = st;
strcpy_s(st, len + 1, ch);
stri.ct = len;
}
void show(const stringy stri, const int n)
{
for (int i = 0; i < n; ++i)
cout << stri.str << endl;
}
void show(const char * ch, int n)
{
for (int i = 0; i < n; ++i)
cout << ch << endl;
}
重要知识点: ①. 需要用变量设置字符串长度时, 需要用new : char * st = new char[len + 1], 设置st指向一个长度为len+1(包含’\0’)的字符串开头; ②. 使用strcpy会报错,应当使用更为安全的strcpy_s: strcpy(st, len + 1, ch) 即把ch中(len+1)个字符复制到st中.
8.5
#include<iostream>
using namespace std;
template<class T> T max5(T a[]);
int main()
{
int a1[5] = { 1, 2, 3, 4, 5 };
double a2[5] = { 1.1, 2.2, 3.5, 4.3, 5.9 };
cout << "Max of a1: " << max5(a1) << endl;
cout << "Max of a2: " << max5(a2);
cin.get();
}
template<class T> T max5(T a[])
{
T max = a[0];
for (int i = 1; i < 5; ++i)
{
if (a[i] > max)
max = a[i];
}
return max;
}
重要知识点: ①. 模板函数 template <class T> 的使用: template<class T> T max5(T a[]).
8.6
#include<iostream>
#include<cstring>
using namespace std;
template<class T> T maxn(T a[], int n);
template<> char * maxn<char *>(char * a[], int n);
int main()
{
const int intN = 6, doubleN = 4, charN = 5;
int a[intN] = { 2,3,1,4,5,6 };
double b[doubleN] = { 1.3, 2.5, 6.4, 5.1 };
char * c[charN] = { "hello", "yo", "homme", "nice to meet you", "how are you?" };
cout << "Max of int: " << maxn(a, intN) << endl;
cout << "Max of double: " << maxn(b, doubleN) << endl;
cout << "Max of char: " << maxn(c, charN) << endl;
cin.get();
}
template<class T> T maxn(T a[], int n)
{
T max = a[0];
for (int i = 0; i < n; ++i)
{
if (a[i] > max)
max = a[i];
}
return max;
}
template<> char * maxn<char *>(char * a[], int n)
{
int * len = new int[n];
int max = 0;
char * ind = a[0];
for (int i = 0; i < n; ++i)
{
len[i] = strlen(a[i]);
if (len[i] > max)
{
max = len[i];
ind = a[i];
}
}
delete[] len;
return ind;
}
重要知识点: ①. 模板函数具体化 template<> char * maxn<char *>(char * a[], int n)
; ②. 函数调用字符串组: char * a[k] 代表k个(k行)字符串的指针组成的指针数组, a[k] == (a + k) ; 对比函数调用二维数组: int ar[][k], 代表k列数组的指针, ar[][k] == (*ar)[k], ar[m][n] = (*(ar + m) + n) ,其中ar为指向第一行第一列数字的指针.
8.7
#include<iostream>
using namespace std;
template<typename T> void SumArray(T arr[], int n);
template<typename T> void SumArray(T * arr[], int n);
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 sum of things:\n";
SumArray(things, 6);
cout << "Listing Me. E's debts:\n";
SumArray(pd, 3);
cin.get();
cin.get();
}
template<typename T>
void SumArray(T arr[], int n)
{
cout << "template A\n";
int sum = 0;
for (int i = 0; i < n; ++i)
sum += arr[i];
cout << sum << endl;
}
template<typename T>
void SumArray(T * arr[], int n)
{
double sum = 0;
cout << "template B\n";
for (int i = 0; i < n; ++i)
sum += *arr[i];
cout << sum << endl;
}
重点知识点: ①. 重载解析选择顺序为: 完全匹配(常规函数由于模板) > 提升转换(如char/short转化为int,float转化为double) > 标准转换(如int转换为char, long转换为double) > 用户定义的转换(如类声明中的定义).