这篇文章包含C++ primer plus (第六版)第七章课本中所有的程序清单
并且博主为每个清单都做了详细解释。
如有失误之处,欢迎大家指正!
// 7.1 calling.cpp -- defining, prototyping, and calling a function
// 将包含特定功能(输入输出流函数)的头文件包含进来
#include <iostream>
// 函数声明(函数原型),作用是告诉编译器在后面的代码中会有一个这种格式的函数(因为函数的定义在函数调用之后,
// 而计算机的执行步骤是自上而下逐条执行,只有在遇到函数调用时才发生跳转。函数声明最重要的是:1、函数返回值类型,
// 2、参数个数及参数类型。编译器将会用函数原型与主函数中的被调函数进行匹配。
void simple();
// 主函数,主函数会与操作系统的接口联系起来。{函数体}
int main()
{
// 名称空间的主要用途是为了避免重名定义,避免因名称多用产生的问题。
// 名称空间,输出输出的符号在名称空间中定义,因此将域名写在函数体中可以使用输入输出符号。
using namespace std;
//cout是ostream中的一个对象,使用此对象可以将“”中的内容打印到屏幕上。
// <<是输入输出流符号
cout << "main() will call the simple() function:\n";
//函数调用,因为此函数是空函数(空函数即没有返回值的函数)因此不能将空函数赋值给一个变量,直接调用其即可
simple();
cout << "main() is finished with the simple() function.\n";
// 主调函数,即main函数的返回值,这个返回值是返回给操作系统,返回0以说明此程序没有问题
return 0;
}
// 函数定义
void simple()
{
using namespace std;
cout << "I'm but a simple function.\n";
}
// 7.2 protos.cpp -- using prototypes and function calls
#include <iostream>
//函数原型,一个没有返回值、有一个int类型参数的空函数
void cheers(int);
//函数原型,一个有double类型返回值、含有一个double类型参数的函数
double cube(double x);
int main()
{
using namespace std;
//函数调用,并将常量5传递给函数作为实际参数
cheers(5);
cout << "Give me a number: ";
//声明定义一个double类型的变量,变量名为side
double side;
//cin与cout一样属于输入流,意思是将外部数据输入并存储在一个数据对象中
cin >> side;
//调用函数cube(),并将side作为实际参数传递给cube()函数,将cube()函数的返回值赋值给
//double类型的变量volume。因为cube()是有返回值的函数,因此可以将其返回值赋给一个变量
double volume = cube(side);
cout << "A " << side << "-foot cube has a volume of ";
cout << volume << " cubic feet.\n";
//调用cheers()函数,并将cube()函数的返回值作为参数传递给cheers()函数作为实际参数。
//Typename()表示的是返回值
cheers(cube(2));
return 0;
}
//函数定义
void cheers(int n)
{
using namespace std;
for (int i = 0; i < n; i++)
{
cout << "Cheers! ";
}
cout << endl;
}
//函数定义
double cube(double x)
{
// 返回一个表达式
return x * x * x;
}
// 7.3 twoarg.cpp -- a function with 2 arguments
#include <iostream>
using namespace std;
void n_chars(char, int);
int main()
{
int times;
char ch;
cout << "Enter a character: ";
cin >> ch;
//循环条件,当ch不是q字符时,输入成立,可以持续输入
while (ch != 'q') // q to quit
{
cout << "Enter an integer: ";
cin >> times;
//调用n_chars()函数,并且传递两个参数:ch和times
n_chars(ch, times); // function with two arguments
cout << "\nEnter another character or press the"
" q-key to quit: ";
cin >> ch;
}
cout << "The value of times is " << times << ".\n";
cout << "Bye\n";
// cin.get();
// cin.get();
return 0;
}
// 函数定义,这个函数所表达的意思是:向屏幕打印(输出)n个c
void n_chars(char c, int n) // displays c n times
{
while (n-- > 0) // continue until n reaches 0
cout << c;
}
// 7.4 lotto.cpp -- probability of winning
#include <iostream>
// Note: some implementations require double instead of long double
// 函数原型,返回值类型是long double,参数类型是unsigned,且有两个参数
long double probability(unsigned numbers, unsigned picks);
int main()
{
using namespace std;
double total, choices;
cout << "Enter the total number of choices on the game card and\n"
"the number of picks allowed:\n";
//循环条件:当cin是double类型的时候,输入判断条件成立,当变量choices<=total时条件成立
//&&逻辑运算符表明当以上两个条件同时成立时,while的入口条件成立
while ((cin >> total >> choices) && choices <= total)
{
cout << "You have one chance in ";
cout << probability(total, choices); // compute the odds
cout << " of winning.\n";
cout << "Next two numbers (q to quit): ";
}
cout << "bye\n";
// cin.get();
// cin.get();
return 0;
}
// the following function calculates the probability of picking picks
// numbers correctly from numbers choices
// 函数定义,此函数实现在一个基数中取某个数的概率
long double probability(unsigned numbers, unsigned picks)
{
long double result = 1.0; // here come some local variables
long double n;
unsigned p;
//在for判断条件中,逗号运算符连接了两个并列判断条件,在这个里只有第二个判断条件是一个p>0
//因为在前面的代码中我们可知(传递的实际参数是total和choices,而choices<=total;
//因此,n>=p,所以p>0相当于已经给n做了条件限制
for (n = numbers, p = picks; p > 0; n--, p--)
result = result * n / p;
return result;
}
// 7.5 arrfun1.cpp -- functions with an array argument
#include <iostream>
//定义一个int类型的变量Arsize,并且将其用const限定符限定表明其始终不可修改,因此在属性上类似为常量
const int ArSize = 8;
//函数原型,声明了一个返回值为int类型,具有两个参数,并且其中一个参数是数组头元素指针的函数原型
int sum_arr(int arr[], int n); // prototype
int main()
{
using namespace std;
//定义了一个函数8个元素,并且各元素类型为int类型的数组(数组需要在声明时就为其赋值,因此声明与赋值同时进行)
int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
// some systems require preceding int with static to
// enable array initialization
//调用函数sum_arr(),并将其返回值赋值给int类型的变量sum
int sum = sum_arr(cookies, ArSize);
cout << "Total cookies eaten: " << sum << "\n";
// cin.get();
return 0;
}
// return the sum of an integer array
//函数定义,此函数实现的功能是将数组中的各元素相加,并将和作为其返回值
int sum_arr(int arr[], int n)
{
int total = 0;
for (int i = 0; i < n; i++)
//数组中的元素通过下标访问
total = total + arr[i];
return total;
}
// 7.6 arrfun2.cpp -- functions with an array argument
#include <iostream>
const int ArSize = 8;
int sum_arr(int arr[], int n);
// use std:: instead of using directive
int main()
{
int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
// some systems require preceding int with static to
// enable array initialization
//没有直接些using namespace std,而是用std::对象调用名称空间中的名称
std::cout << cookies << " = array address, ";
// some systems require a type cast: unsigned (cookies)
// sizeof 数组名称的返回值是整个数组的内存长度
std::cout << sizeof cookies << " = sizeof cookies\n";
//将数组名称cookies作为参数传递给函数,这里传递的实际上时数组第一个元素的地址,而Arsize是元素个数
//通过数组第一个元素的地址与元素的个数,会使得数组中的全部元素被访问
int sum = sum_arr(cookies, ArSize);
std::cout << "Total cookies eaten: " << sum << std::endl;
//被调函数第二个实际参数为3表明只访问前三个元素
sum = sum_arr(cookies, 3); // a lie
std::cout << "First three eaters ate " << sum << " cookies.\n";
//被调函数的第一个参数是cookies+4,cookies是数组名称,代表的是数组第一个元素的地址,地址+4意味着
//地址将会向后移动四个地址,因此将从第5个元素开始
sum = sum_arr(cookies + 4, 4); // another lie
std::cout << "Last four eaters ate " << sum << " cookies.\n";
// std::cin.get();
return 0;
}
// return the sum of an integer array
//函数定义,此函数实现数组各个元素相加并将其和作为返回值的功能
int sum_arr(int arr[], int n)
{
int total = 0;
std::cout << arr << " = arr, ";
// some systems require a type cast: unsigned (arr)
//sizeof on array function parameter will return size of 'int *' instead of 'int []'
//将sizeof功能作用在一个作为函数参数的数组,其返回值是一个int类型的指针,而不是int类型的数组
std::cout << sizeof (arr) << " = sizeof arr\n";
for (int i = 0; i < n; i++)
total = total + arr[i];
return total;
}
// 7.7 arrfun3.cpp -- array functions and const
#include <iostream>
const int Max = 5;
// function prototypes
//函数原型,返回值为int类型,有两个参数,一个是double类型的数组,一个是int类型。
int fill_array(double ar[], int limit);
//函数原型,没有返回值,有两个参数,其中一个为不可修改的double类型的数组,一个是int类型的值
void show_array(const double ar[], int n); // don't change data
void revalue(double r, double ar[], int n);
int main()
{
using namespace std;
double properties[Max];
//将fill_array()函数的返回值赋值给变量size
int size = fill_array(properties, Max);
show_array(properties, size);
if (size > 0)
{
cout << "Enter revaluation factor: ";
double factor;
//这个循环条件意味着,如果cin>>factor是合理的,那么cin将会把输入的值赋给factor
//如果cin>>factor是不合理的,那么就会开启while函数体中的代码
while (!(cin >> factor)) // bad input
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; Please enter a number: ";
}
revalue(factor, properties, size);
show_array(properties, size);
}
cout << "Done.\n";
// cin.get();
// cin.get();
return 0;
}
int fill_array(double ar[], int limit)
{
using namespace std;
double temp;
int i;
for (i = 0; i < limit; i++)
{
cout << "Enter value #" << (i + 1) << ": ";
cin >> temp;
//如果cin>>temp是不合理的,那么被输入的不合理的值将被留在队列中
//因此if(!cin)可以作为一个判断条件
if (!cin) // bad input
{
cin.clear();
while (cin.get() != '\n')
continue;
cout << "Bad input; input process terminated.\n";
break;
}
else if (temp < 0) // signal to terminate
break;
ar[i] = temp;
}
return i;
}
// the following function can use, but not alter,
// the array whose address is ar
void show_array(const double ar[], int n)
{
using namespace std;
for (int i = 0; i < n; i++)
{
cout << "Property #" << (i + 1) << ": $";
cout << ar[i] << endl;
}
}
// multiplies each element of ar[] by r
void revalue(double r, double ar[], int n)
{
for (int i = 0; i < n; i++)
ar[i] *= r;
}